Skip to content

Commit 5c497d1

Browse files
committed
[capture] Enable uJSON for OTBN
This commit enables communication with the OTBN SCA code over uJSON. The device code is located in lowRISC/opentitan#22190. Signed-off-by: Pascal Nasahl <[email protected]>
1 parent c4575d2 commit 5c497d1

10 files changed

+458
-71
lines changed

.github/workflows/fpga.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,65 @@ jobs:
148148
name: traces_sha3_random_cw310_ujson
149149
path: ./ci/projects/sha3_sca_random_cw310_ujson.html
150150

151+
otbn_sca_capture_cw310:
152+
name: Capture OTBN SCA traces (CW310)
153+
runs-on: [ubuntu-22.04-fpga, cw310]
154+
timeout-minutes: 30
155+
156+
steps:
157+
- uses: actions/checkout@v4
158+
with:
159+
lfs: true
160+
161+
- name: Install python dependencies
162+
run: |
163+
python3 -m pip install --user -r python-requirements.txt
164+
mkdir -p ci/projects
165+
166+
- name: Capture OTBN Vertical Keygen traces (simpleserial)
167+
working-directory: ci
168+
run: |
169+
../capture/capture_otbn.py -c cfg/ci_otbn_sca_vertical_keygen_cw310_simpleserial.yaml -p projects/otbn_sca_vertical_keygen_cw310_simpleserial
170+
171+
- name: Upload OTBN Vertical Keygen traces (simpleserial)
172+
uses: actions/upload-artifact@v4
173+
with:
174+
name: traces_otbn_sca_vertical_keygen_cw310_simpleserial
175+
path: ./ci/projects/otbn_sca_vertical_keygen_cw310_simpleserial.html
176+
177+
- name: Capture OTBN Vertical Keygen traces (ujson)
178+
working-directory: ci
179+
run: |
180+
../capture/capture_otbn.py -c cfg/ci_otbn_sca_vertical_keygen_cw310_ujson.yaml -p projects/otbn_sca_vertical_keygen_cw310_ujson
181+
182+
- name: Upload OTBN Vertical Keygen traces (ujson)
183+
uses: actions/upload-artifact@v4
184+
with:
185+
name: traces_otbn_sca_vertical_keygen_cw310_ujson
186+
path: ./ci/projects/otbn_sca_vertical_keygen_cw310_ujson.html
187+
188+
- name: Capture OTBN Vertical Modinv traces (simpleserial)
189+
working-directory: ci
190+
run: |
191+
../capture/capture_otbn.py -c cfg/ci_otbn_sca_vertical_modinv_cw310_simpleserial.yaml -p projects/otbn_sca_vertical_modinv_cw310_simpleserial
192+
193+
- name: Upload OTBN Vertical Modinv traces (simpleserial)
194+
uses: actions/upload-artifact@v4
195+
with:
196+
name: traces_otbn_sca_vertical_modinv_cw310_simpleserial
197+
path: ./ci/projects/otbn_sca_vertical_modinv_cw310_simpleserial.html
198+
199+
- name: Capture OTBN Vertical Modinv traces (ujson)
200+
working-directory: ci
201+
run: |
202+
../capture/capture_otbn.py -c cfg/ci_otbn_sca_vertical_modinv_cw310_ujson.yaml -p projects/otbn_sca_vertical_modinv_cw310_ujson
203+
204+
- name: Upload OTBN Vertical Modinv traces (ujson)
205+
uses: actions/upload-artifact@v4
206+
with:
207+
name: traces_otbn_sca_vertical_modinv_cw310_ujson
208+
path: ./ci/projects/otbn_sca_vertical_modinv_cw310_ujson.html
209+
151210
sca_capture_cw305:
152211
name: Capture AES SCA traces (CW305)
153212
runs-on: [ubuntu-22.04-fpga, cw305]

capture/capture_otbn.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import util.helpers as helpers
2424
from target.communication.sca_otbn_commands import OTOTBNVERT
25+
from target.communication.sca_prng_commands import OTPRNG
2526
from target.communication.sca_trigger_commands import OTTRIGGER
2627
from target.targets import Target, TargetConfig
2728
from util import check_version
@@ -191,39 +192,45 @@ def establish_communication(target, capture_cfg: CaptureConfig):
191192
192193
Returns:
193194
ot_otbn_vert: The communication interface to the OTBN app.
195+
ot_prng: The communication interface to the PRNG SCA application.
194196
ot_trig: The communication interface to the SCA trigger.
195197
"""
196198
# Create communication interface to OTBN.
197199
ot_otbn_vert = OTOTBNVERT(target=target, protocol=capture_cfg.protocol)
198200

201+
# Create communication interface to OT PRNG.
202+
ot_prng = OTPRNG(target=target, protocol=capture_cfg.protocol)
203+
199204
# Create communication interface to SCA trigger.
200205
ot_trig = OTTRIGGER(target=target, protocol=capture_cfg.protocol)
201206

202-
return ot_otbn_vert, ot_trig
207+
return ot_otbn_vert, ot_prng, ot_trig
203208

204209

205-
def configure_cipher(cfg: dict, target, capture_cfg: CaptureConfig,
206-
ot_otbn_vert) -> OTOTBNVERT:
210+
def configure_cipher(cfg: dict, capture_cfg: CaptureConfig, ot_otbn_vert,
211+
ot_prng) -> OTOTBNVERT:
207212
""" Configure the OTBN app.
208213
209214
Establish communication with the OTBN keygen app and configure the seed.
210215
211216
Args:
212217
cfg: The configuration for the current experiment.
213-
target: The OT target.
214218
curve_cfg: The curve config.
215219
capture_cfg: The configuration of the capture.
216220
ot_otbn_vert: The communication interface to the OTBN app.
221+
ot_prng: The communication interface to the PRNG SCA application.
217222
218223
Returns:
219224
curve_cfg: The curve configuration values.
220225
"""
226+
# Initialize OTBN on the target.
227+
ot_otbn_vert.init()
228+
221229
# Seed host's PRNG.
222230
random.seed(cfg["test"]["batch_prng_seed"])
223231

224232
# Seed the target's PRNGs
225-
ot_otbn_vert.write_batch_prng_seed(cfg["test"]["batch_prng_seed"].to_bytes(
226-
4, "little"))
233+
ot_prng.seed_prng(cfg["test"]["batch_prng_seed"].to_bytes(4, "little"))
227234

228235
# select the otbn app on the device (0 -> keygen, 1 -> modinv)
229236
ot_otbn_vert.choose_otbn_app(cfg["test"]["app"])
@@ -474,12 +481,7 @@ def check_ciphertext_keygen(ot_otbn_vert: OTOTBNVERT, expected_key,
474481
"""
475482
# Read the output, unmask the key, and check if it matches
476483
# expectations.
477-
share0 = ot_otbn_vert.read_output(curve_cfg.seed_bytes)
478-
share1 = ot_otbn_vert.read_output(curve_cfg.seed_bytes)
479-
if share0 is None:
480-
raise RuntimeError('Random share0 is none')
481-
if share1 is None:
482-
raise RuntimeError('Random share1 is none')
484+
share0, share1 = ot_otbn_vert.read_seeds(curve_cfg.seed_bytes)
483485

484486
d0 = int.from_bytes(share0, byteorder='little')
485487
d1 = int.from_bytes(share1, byteorder='little')
@@ -505,8 +507,7 @@ def check_ciphertext_modinv(ot_otbn_vert: OTOTBNVERT, expected_output,
505507
actual_output: The received output of the modinv operation.
506508
"""
507509
# Read the output, unmask it, and check if it matches expectations.
508-
kalpha_inv = ot_otbn_vert.read_output(curve_cfg.key_bytes)
509-
alpha = ot_otbn_vert.read_output(curve_cfg.modinv_mask_bytes)
510+
kalpha_inv, alpha = ot_otbn_vert.read_alpha(curve_cfg.key_bytes, curve_cfg.modinv_mask_bytes)
510511
if kalpha_inv is None:
511512
raise RuntimeError('kaplpha_inv is none')
512513
if alpha is None:
@@ -589,8 +590,8 @@ def capture_keygen(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBNVERT,
589590

590591
# Store trace into database.
591592
project.append_trace(wave=waves[0, :],
592-
plaintext=mask,
593-
ciphertext=share0 + share1,
593+
plaintext=bytearray(mask),
594+
ciphertext=bytearray(share0 + share1),
594595
key=seed_used)
595596

596597
# Memory allocation optimization for CW trace library.
@@ -660,11 +661,11 @@ def capture_modinv(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBNVERT,
660661

661662
# Store trace into database.
662663
project.append_trace(wave=waves[0, :],
663-
plaintext=k_used,
664+
plaintext=bytearray(k_used),
664665
ciphertext=bytearray(
665666
actual_output.to_bytes(
666667
curve_cfg.key_bytes, 'little')),
667-
key=k_used)
668+
key=bytearray(k_used))
668669

669670
# Memory allocation optimization for CW trace library.
670671
num_segments_storage = project.optimize_capture(
@@ -729,6 +730,7 @@ def main(argv=None):
729730
key_len_bytes=cfg["test"]["key_len_bytes"],
730731
text_len_bytes=cfg["test"]["text_len_bytes"],
731732
protocol=cfg["target"]["protocol"],
733+
port = cfg["target"].get("port"),
732734
C=bytearray(),
733735
seed_fixed=bytearray(),
734736
expected_fixed_key=bytearray(),
@@ -739,10 +741,10 @@ def main(argv=None):
739741
)
740742

741743
# Open communication with target.
742-
ot_otbn_vert, ot_trig = establish_communication(target, capture_cfg)
744+
ot_otbn_vert, ot_prng, ot_trig = establish_communication(target, capture_cfg)
743745

744746
# Configure cipher.
745-
curve_cfg = configure_cipher(cfg, target, capture_cfg, ot_otbn_vert)
747+
curve_cfg = configure_cipher(cfg, capture_cfg, ot_otbn_vert, ot_prng)
746748

747749
# Configure trigger source.
748750
# 0 for HW, 1 for SW.

capture/configs/otbn_vertical_keygen_sca_cw310.yaml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,31 @@ target:
22
target_type: cw310
33
fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit"
44
force_program_bitstream: True
5-
fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
5+
# fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
6+
fw_bin: ../objs/sca_ujson_fpga_cw310.bin
67
# target_clk_mult is a hardcoded value in the bitstream. Do not change.
78
target_clk_mult: 0.24
89
target_freq: 24000000
910
baudrate: 115200
1011
output_len_bytes: 40
11-
protocol: "simpleserial"
12-
# protocol: "ujson"
13-
# port: "/dev/ttyACM4"
12+
# protocol: "simpleserial"
13+
protocol: "ujson"
14+
port: "/dev/ttyACM4"
1415
# Trigger source.
1516
# hw: Precise, hardware-generated trigger - FPGA only.
1617
# sw: Fully software-controlled trigger.
1718
trigger: "hw"
1819
husky:
1920
sampling_rate: 200000000
20-
num_segments: 20
21+
num_segments: 1
2122
num_cycles: 200
2223
offset_cycles: 0
2324
scope_gain: 24
2425
adc_mul: 1
2526
decimate: 1
2627
waverunner:
2728
waverunner_ip: 100.107.71.10
28-
num_segments: 20
29+
num_segments: 1
2930
num_samples: 6000
3031
sample_offset: 0
3132
capture:

capture/configs/otbn_vertical_modinv_sca_cw310.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ target:
22
target_type: cw310
33
fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit"
44
force_program_bitstream: True
5-
fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
5+
# fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
6+
fw_bin: ../objs/sca_ujson_fpga_cw310.bin
67
# target_clk_mult is a hardcoded value in the bitstream. Do not change.
78
target_clk_mult: 0.24
89
target_freq: 24000000
910
baudrate: 115200
1011
output_len_bytes: 40
11-
protocol: "simpleserial"
12-
# protocol: "ujson"
13-
# port: "/dev/ttyACM4"
12+
# protocol: "simpleserial"
13+
protocol: "ujson"
14+
port: "/dev/ttyACM4"
1415
# Trigger source.
1516
# hw: Precise, hardware-generated trigger - FPGA only.
1617
# sw: Fully software-controlled trigger.
17-
trigger: "hw"
18+
trigger: "sw"
1819
husky:
1920
sampling_rate: 200000000
2021
num_segments: 20
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
target:
2+
target_type: cw310
3+
fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit"
4+
force_program_bitstream: False
5+
fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
6+
# target_clk_mult is a hardcoded value in the bitstream. Do not change.
7+
target_clk_mult: 0.24
8+
target_freq: 24000000
9+
baudrate: 115200
10+
output_len_bytes: 40
11+
protocol: "simpleserial"
12+
# Trigger source.
13+
# hw: Precise, hardware-generated trigger - FPGA only.
14+
# sw: Fully software-controlled trigger.
15+
trigger: "hw"
16+
husky:
17+
sampling_rate: 200000000
18+
num_segments: 1
19+
num_cycles: 200
20+
offset_cycles: 0
21+
scope_gain: 24
22+
adc_mul: 1
23+
decimate: 1
24+
capture:
25+
scope_select: husky
26+
show_plot: True
27+
plot_traces: 10
28+
num_traces: 100
29+
trace_threshold: 10000
30+
trace_db: ot_trace_library
31+
test:
32+
batch_prng_seed: 6
33+
key_len_bytes: 40
34+
text_len_bytes: 40
35+
plain_text_len_bytes: 40
36+
masks_off: False
37+
# Currently, 'p256' is the only supported curve.
38+
curve: p256
39+
# Select the OTBN app to analyze. Currently available: 'keygen', 'modinv'
40+
app: keygen
41+
# For app = keygen: There are two fixed-vs-random test types, KEY and SEED
42+
# Currently batch-mode capture only works with SEED
43+
test_type: SEED
44+
batch_mode: False
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
target:
2+
target_type: cw310
3+
fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit"
4+
force_program_bitstream: False
5+
fw_bin: ../objs/sca_ujson_fpga_cw310.bin
6+
# target_clk_mult is a hardcoded value in the bitstream. Do not change.
7+
target_clk_mult: 0.24
8+
target_freq: 24000000
9+
baudrate: 115200
10+
output_len_bytes: 40
11+
protocol: "ujson"
12+
port: "/dev/ttyACM_CW310_1"
13+
# Trigger source.
14+
# hw: Precise, hardware-generated trigger - FPGA only.
15+
# sw: Fully software-controlled trigger.
16+
trigger: "hw"
17+
husky:
18+
sampling_rate: 200000000
19+
num_segments: 1
20+
num_cycles: 200
21+
offset_cycles: 0
22+
scope_gain: 24
23+
adc_mul: 1
24+
decimate: 1
25+
capture:
26+
scope_select: husky
27+
show_plot: True
28+
plot_traces: 10
29+
num_traces: 100
30+
trace_threshold: 10000
31+
trace_db: ot_trace_library
32+
test:
33+
batch_prng_seed: 6
34+
key_len_bytes: 40
35+
text_len_bytes: 40
36+
plain_text_len_bytes: 40
37+
masks_off: False
38+
# Currently, 'p256' is the only supported curve.
39+
curve: p256
40+
# Select the OTBN app to analyze. Currently available: 'keygen', 'modinv'
41+
app: keygen
42+
# For app = keygen: There are two fixed-vs-random test types, KEY and SEED
43+
# Currently batch-mode capture only works with SEED
44+
test_type: SEED
45+
batch_mode: False
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
target:
2+
target_type: cw310
3+
fpga_bitstream: "../objs/lowrisc_systems_chip_earlgrey_cw310_0.1.bit"
4+
force_program_bitstream: False
5+
fw_bin: "../objs/otbn_vertical_serial_fpga_cw310.bin"
6+
# target_clk_mult is a hardcoded value in the bitstream. Do not change.
7+
target_clk_mult: 0.24
8+
target_freq: 24000000
9+
baudrate: 115200
10+
output_len_bytes: 40
11+
protocol: "simpleserial"
12+
# Trigger source.
13+
# hw: Precise, hardware-generated trigger - FPGA only.
14+
# sw: Fully software-controlled trigger.
15+
trigger: "sw"
16+
husky:
17+
sampling_rate: 200000000
18+
num_segments: 20
19+
num_cycles: 1000
20+
offset_cycles: 0
21+
scope_gain: 24
22+
adc_mul: 1
23+
decimate: 1
24+
capture:
25+
scope_select: husky
26+
show_plot: True
27+
plot_traces: 10
28+
num_traces: 100
29+
trace_threshold: 10000
30+
trace_db: ot_trace_library
31+
test:
32+
batch_prng_seed: 6
33+
key_len_bytes: 40
34+
text_len_bytes: 40
35+
plain_text_len_bytes: 40
36+
masks_off: False
37+
# Currently, 'p256' is the only supported curve.
38+
curve: p256
39+
# Select the OTBN app to analyze. Currently available: 'keygen', 'modinv'
40+
app: modinv
41+
# For app = keygen: There are two fixed-vs-random test types, KEY and SEED
42+
# Currently batch-mode capture only works with SEED
43+
test_type: SEED
44+
batch_mode: False

0 commit comments

Comments
 (0)