Skip to content

Commit cf7d695

Browse files
committed
[fisim/crypto] Add instruction skip simulator
Add a script to load the pentest framework, connect to OpenOCD, and connect to GDB. Generate a trace file of a called function. Use the trace file to insert instruction skips in order to simulate fault attacks and test countermeasures. Signed-off-by: Siemen Dhooghe <[email protected]>
1 parent b0714dc commit cf7d695

File tree

12 files changed

+3319
-76
lines changed

12 files changed

+3319
-76
lines changed

sw/device/tests/penetrationtests/BUILD

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
33
# SPDX-License-Identifier: Apache-2.0
44

5-
load(":pentest.bzl", "pentest_cryptolib_fi_asym", "pentest_cryptolib_fi_sym", "pentest_cryptolib_sca_asym", "pentest_cryptolib_sca_sym", "pentest_fi", "pentest_fi_ibex", "pentest_fi_otbn", "pentest_sca")
5+
load(":pentest.bzl", "pentest_cryptolib_fi_asym", "pentest_cryptolib_fi_gdb_asym", "pentest_cryptolib_fi_gdb_sym", "pentest_cryptolib_fi_sym", "pentest_cryptolib_sca_asym", "pentest_cryptolib_sca_sym", "pentest_fi", "pentest_fi_ibex", "pentest_fi_otbn", "pentest_sca")
66
load("@ot_python_deps//:requirements.bzl", "requirement")
77

88
package(default_visibility = ["//visibility:public"])
@@ -287,6 +287,17 @@ pentest_cryptolib_fi_asym(
287287
test_vectors = CRYPTOLIB_FI_ASYM_TESTVECTOR_TARGETS,
288288
)
289289

290+
pentest_cryptolib_fi_gdb_sym(
291+
name = "fi_sym_cryptolib_python_gdb_test",
292+
tags = [
293+
"manual",
294+
"skip_in_ci",
295+
],
296+
test_args = "",
297+
test_harness = "//sw/host/penetrationtests/python/fi:fi_sym_cryptolib_python_gdb_test",
298+
test_vectors = [],
299+
)
300+
290301
pentest_cryptolib_fi_asym(
291302
name = "fi_asym_cryptolib_python_test",
292303
tags = [],
@@ -295,6 +306,17 @@ pentest_cryptolib_fi_asym(
295306
test_vectors = [],
296307
)
297308

309+
pentest_cryptolib_fi_gdb_asym(
310+
name = "fi_asym_cryptolib_python_gdb_test",
311+
tags = [
312+
"manual",
313+
"skip_in_ci",
314+
],
315+
test_args = "",
316+
test_harness = "//sw/host/penetrationtests/python/fi:fi_asym_cryptolib_python_gdb_test",
317+
test_vectors = [],
318+
)
319+
298320
CRYPTOLIB_SCA_SYM_TESTVECTOR_TARGETS = [
299321
"//sw/host/penetrationtests/testvectors/data:sca_sym_cryptolib",
300322
]

sw/device/tests/penetrationtests/doc/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@ cd $REPO_TOP
7676
./bazelisk.sh run //sw/device/tests/penetrationtests:fi_ibex_python_test_fpga_cw340_sival_rom_ext
7777
```
7878

79+
## GDB Testing (FiSim)
80+
81+
The crypto library is tested on a debug enabled CW340 FPGA by tracing several relevant cryptographic calls and apply instruction skips or other fault models to their execution. In order to use this testing, the CW340 FPGA has to be adapted. We provide a picture on its setup as reference:
82+
83+
![CW340 debug setup](fi_sim_cw340_setup.png)
84+
85+
In order to run a GDB test, find the "gdb_test" targets in the BUILD file in //sw/device/tests/penetrationtests. For example,
86+
```console
87+
./bazelisk.sh run //sw/device/tests/penetrationtests:fi_sym_cryptolib_python_gdb_test_fpga_cw340_rom_ext
88+
89+
./bazelisk.sh run //sw/device/tests/penetrationtests:fi_asym_cryptolib_python_gdb_test_fpga_cw340_rom_ext
90+
```
91+
92+
These tests specifically run in the rom_ext environment since this is a ROM version in the RMA lifecycle which enables debug. The test then builds and runs openocd in the background which opens the default port 3333 to GDB. The files in //sw/host/penetrationtests/python/util contain classes in order to communicate with the FPGA, OpenOCD, and GDB.
93+
94+
The testing is performed on the flashed pentest framework in this directory which provides the interface to the crypto library in //sw/device/lib/crypto. The targeted functions are found parsing the dis file. The parser is also found in //sw/host/penetrationtests/python/util.
95+
96+
All test outputs are saved in the bazel-testlogs/sw/device/tests/penetrationtests folder in opentitan. Take note that the output to the terminal is piped to the campaign file in that directory, please consult this file for the test output. This is done since each subtest can take 2-12h.
97+
7998
## Versioning
8099

81100
In `//sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h`, a value PENTEST_VERSION is found with the current version of the pentest framework.

sw/device/tests/penetrationtests/pentest.bzl

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ PENTEST_EXEC_ENVS = {
2424
"//hw/top_earlgrey:fpga_cw340_rom_ext": "fpga_cw340",
2525
} | EARLGREY_SILICON_OWNER_ROM_EXT_ENVS
2626

27+
GDB_EXEC_ENVS = {
28+
"//hw/top_earlgrey:fpga_cw340_rom_ext": "fpga_cw340",
29+
}
30+
2731
FIRMWARE_DEPS_FI = [
2832
"//sw/device/tests/penetrationtests/firmware/fi:alert_fi",
2933
"//sw/device/tests/penetrationtests/firmware/fi:crypto_fi",
@@ -388,6 +392,50 @@ def pentest_cryptolib_fi_sym(name, test_vectors, test_args, test_harness, tags):
388392
deps = FIRMWARE_DEPS_CRYPTOLIB_FI_SYM,
389393
)
390394

395+
def pentest_cryptolib_fi_gdb_sym(name, test_vectors, test_args, test_harness, tags):
396+
"""A macro for defining a CryptoTest test case.
397+
398+
Args:
399+
name: the name of the test.
400+
test_vectors: the test vectors to use.
401+
test_args: additional arguments to pass to the test.
402+
test_harness: the test harness to use.
403+
tags: indicate the tags for CI.
404+
"""
405+
opentitan_test(
406+
name = name,
407+
srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_fi_sym.c"],
408+
fpga = fpga_params(
409+
timeout = "long",
410+
data = test_vectors,
411+
tags = tags,
412+
test_cmd = """
413+
--bootstrap={firmware}
414+
""" + test_args,
415+
test_harness = test_harness,
416+
),
417+
fpga_cw340 = fpga_params(
418+
timeout = "long",
419+
tags = tags,
420+
data = test_vectors,
421+
test_cmd = """
422+
--bootstrap={firmware}
423+
""" + test_args,
424+
test_harness = test_harness,
425+
),
426+
exec_env = GDB_EXEC_ENVS,
427+
silicon = silicon_params(
428+
timeout = "eternal",
429+
tags = tags,
430+
data = test_vectors,
431+
test_cmd = """
432+
--bootstrap={firmware}
433+
""" + test_args,
434+
test_harness = test_harness,
435+
),
436+
deps = FIRMWARE_DEPS_CRYPTOLIB_FI_SYM,
437+
)
438+
391439
def pentest_cryptolib_fi_asym(name, test_vectors, test_args, test_harness, tags):
392440
"""A macro for defining a CryptoTest test case.
393441
@@ -432,6 +480,50 @@ def pentest_cryptolib_fi_asym(name, test_vectors, test_args, test_harness, tags)
432480
deps = FIRMWARE_DEPS_CRYPTOLIB_FI_ASYM,
433481
)
434482

483+
def pentest_cryptolib_fi_gdb_asym(name, test_vectors, test_args, test_harness, tags):
484+
"""A macro for defining a CryptoTest test case.
485+
486+
Args:
487+
name: the name of the test.
488+
test_vectors: the test vectors to use.
489+
test_args: additional arguments to pass to the test.
490+
test_harness: the test harness to use.
491+
tags: indicate the tags for CI.
492+
"""
493+
opentitan_test(
494+
name = name,
495+
srcs = ["//sw/device/tests/penetrationtests/firmware:firmware_cryptolib_fi_asym.c"],
496+
fpga = fpga_params(
497+
timeout = "long",
498+
data = test_vectors,
499+
tags = tags,
500+
test_cmd = """
501+
--bootstrap={firmware}
502+
""" + test_args,
503+
test_harness = test_harness,
504+
),
505+
fpga_cw340 = fpga_params(
506+
timeout = "long",
507+
tags = tags,
508+
data = test_vectors,
509+
test_cmd = """
510+
--bootstrap={firmware}
511+
""" + test_args,
512+
test_harness = test_harness,
513+
),
514+
exec_env = GDB_EXEC_ENVS,
515+
silicon = silicon_params(
516+
timeout = "eternal",
517+
tags = tags,
518+
data = test_vectors,
519+
test_cmd = """
520+
--bootstrap={firmware}
521+
""" + test_args,
522+
test_harness = test_harness,
523+
),
524+
deps = FIRMWARE_DEPS_CRYPTOLIB_FI_ASYM,
525+
)
526+
435527
def pentest_cryptolib_sca_sym(name, test_vectors, test_args, test_harness, tags):
436528
"""A macro for defining a CryptoTest test case.
437529

sw/host/penetrationtests/python/fi/BUILD

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,28 @@ py_binary(
150150
],
151151
)
152152

153+
py_binary(
154+
name = "fi_sym_cryptolib_python_gdb_test",
155+
testonly = True,
156+
srcs = ["gdb_testing/fi_sym_cryptolib_python_gdb_test.py"],
157+
data = [
158+
"//sw/host/opentitantool",
159+
"//third_party/openocd:openocd_bin",
160+
"//util/openocd/board:cw340_ftdi.cfg",
161+
"//util/openocd/target:lowrisc-earlgrey.cfg",
162+
"@lowrisc_rv32imcb_toolchain//:bin/riscv32-unknown-elf-gdb",
163+
],
164+
deps = [
165+
"//sw/host/penetrationtests/python/fi:fi_sym_cryptolib_commands",
166+
"//sw/host/penetrationtests/python/util:common_library",
167+
"//sw/host/penetrationtests/python/util:dis_parser",
168+
"//sw/host/penetrationtests/python/util:gdb_controller",
169+
"//sw/host/penetrationtests/python/util:targets",
170+
"@rules_python//python/runfiles",
171+
requirement("pycryptodome"),
172+
],
173+
)
174+
153175
py_binary(
154176
name = "fi_asym_cryptolib_python_test",
155177
testonly = True,
@@ -168,6 +190,28 @@ py_binary(
168190
],
169191
)
170192

193+
py_binary(
194+
name = "fi_asym_cryptolib_python_gdb_test",
195+
testonly = True,
196+
srcs = ["gdb_testing/fi_asym_cryptolib_python_gdb_test.py"],
197+
data = [
198+
"//sw/host/opentitantool",
199+
"//third_party/openocd:openocd_bin",
200+
"//util/openocd/board:cw340_ftdi.cfg",
201+
"//util/openocd/target:lowrisc-earlgrey.cfg",
202+
"@lowrisc_rv32imcb_toolchain//:bin/riscv32-unknown-elf-gdb",
203+
],
204+
deps = [
205+
"//sw/host/penetrationtests/python/fi:fi_asym_cryptolib_commands",
206+
"//sw/host/penetrationtests/python/util:common_library",
207+
"//sw/host/penetrationtests/python/util:dis_parser",
208+
"//sw/host/penetrationtests/python/util:gdb_controller",
209+
"//sw/host/penetrationtests/python/util:targets",
210+
"@rules_python//python/runfiles",
211+
requirement("pycryptodome"),
212+
],
213+
)
214+
171215
py_library(
172216
name = "fi_ibex_functions",
173217
srcs = ["host_scripts/fi_ibex_functions.py"],

0 commit comments

Comments
 (0)