Skip to content

Commit

Permalink
[ci] Automatic comparison of traces
Browse files Browse the repository at this point in the history
This PR adds a new CI job to automatically compare a generated
trace to a golden reference trace. This helps to quickly
identify CI issues.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa committed Oct 11, 2023
1 parent 698b81a commit c3c3d69
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 3 deletions.
8 changes: 8 additions & 0 deletions ci/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,11 @@ jobs:
- publish: ./ci/ci_projects/opentitan_simple_aes_data/
artifact: traces
displayName: "Upload traces"
- bash: |
pushd ci
./ci_check_aes_traces.sh
popd
displayName: "Capture & check static AES traces"
- publish: ./ci/tmp/
artifact: traces
displayName: "Upload traces AES."
6 changes: 3 additions & 3 deletions ci/ci_capture_aes_cw310.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ capture:
project_name: ci_projects/opentitan_simple_aes
waverunner_ip: 192.168.1.228
plot_capture:
show: False
num_traces: 100
trace_image_filename: null
show: True
num_traces: 2
trace_image_filename: ci_projects/sample_traces_aes.html
25 changes: 25 additions & 0 deletions ci/ci_check_aes_traces.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

# Simple script to test AES captures
# Create results folder.
mkdir -p tmp

# AES
MODE="aes"
BOARD=cw310
declare -A aes_test_list
aes_test_list["aes-static"]=2

ARGS="--force-program-bitstream"
for test in ${!aes_test_list[@]}; do
echo Testing ${test} on CW310 - `date`
NUM_TRACES=${aes_test_list[${test}]}
../cw/capture.py --cfg-file ci_capture_aes_cw310.yaml capture ${test} \
--num-traces ${NUM_TRACES} ${ARGS} &>> "tmp/test_capture.log"

mv ./ci_projects/sample_traces_${MODE}.html tmp/${test}_traces.html
ARGS=""
done
37 changes: 37 additions & 0 deletions cw/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,43 @@ def capture_end(cfg):
plot_results(cfg["plot_capture"], cfg["capture"]["project_name"])


def capture_aes_static(ot):
"""A generator for capturing AES traces for fixed key and test.
Args:
ot: Initialized OpenTitan target.
"""
key = bytearray([0x81, 0x1E, 0x37, 0x31, 0xB0, 0x12, 0x0A, 0x78,
0x42, 0x78, 0x1E, 0x22, 0xB2, 0x5C, 0xDD, 0xF9])
text = bytearray([0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA])

tqdm.write(f'Fixed key: {binascii.b2a_hex(bytes(key))}')

while True:
cipher = AES.new(bytes(key), AES.MODE_ECB)
ret = cw.capture_trace(ot.scope, ot.target, text, key, ack=False, as_int=True)
if not ret:
raise RuntimeError('Capture failed.')
expected = binascii.b2a_hex(cipher.encrypt(bytes(text)))
got = binascii.b2a_hex(ret.textout)
if got != expected:
raise RuntimeError(f'Bad ciphertext: {got} != {expected}.')
yield ret


@app_capture.command()
def aes_static(ctx: typer.Context,
force_program_bitstream: bool = opt_force_program_bitstream,
num_traces: int = opt_num_traces,
plot_traces: int = opt_plot_traces):
"""Capture AES traces from a target that runs the `aes_serial` program."""
capture_init(ctx, force_program_bitstream, num_traces, plot_traces)
capture_loop(capture_aes_static(ctx.obj.ot), ctx.obj.ot,
ctx.obj.cfg["capture"], ctx.obj.cfg["device"])
capture_end(ctx.obj.cfg)


def capture_aes_random(ot, ktp):
"""A generator for capturing AES traces.
Fixed key, Random texts.
Expand Down

0 comments on commit c3c3d69

Please sign in to comment.