Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sca] Add KeySideloadFvsr OTBN test #373

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions capture/capture_otbn.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from tqdm import tqdm

import util.helpers as helpers
from target.communication.sca_otbn_commands import OTOTBNVERT
from target.communication.sca_otbn_commands import OTOTBN
from target.communication.sca_trigger_commands import OTTRIGGER
from target.targets import Target, TargetConfig
from util import check_version
Expand Down Expand Up @@ -194,7 +194,7 @@ def establish_communication(target, capture_cfg: CaptureConfig):
ot_trig: The communication interface to the SCA trigger.
"""
# Create communication interface to OTBN.
ot_otbn_vert = OTOTBNVERT(target=target, protocol=capture_cfg.protocol)
ot_otbn_vert = OTOTBN(target=target, protocol=capture_cfg.protocol)

# Create communication interface to SCA trigger.
ot_trig = OTTRIGGER(target=target, protocol=capture_cfg.protocol)
Expand All @@ -203,7 +203,7 @@ def establish_communication(target, capture_cfg: CaptureConfig):


def configure_cipher(cfg: dict, target, capture_cfg: CaptureConfig,
ot_otbn_vert) -> OTOTBNVERT:
ot_otbn_vert) -> OTOTBN:
""" Configure the OTBN app.

Establish communication with the OTBN keygen app and configure the seed.
Expand Down Expand Up @@ -455,7 +455,7 @@ def generate_ref_crypto_modinv(cfg: dict, sample_fixed, curve_cfg: CurveConfig,
return k_used, input_k0_used, input_k1_used, expected_output, sample_fixed


def check_ciphertext_keygen(ot_otbn_vert: OTOTBNVERT, expected_key,
def check_ciphertext_keygen(ot_otbn_vert: OTOTBN, expected_key,
curve_cfg: CurveConfig):
""" Compares the received with the generated key.

Expand Down Expand Up @@ -492,7 +492,7 @@ def check_ciphertext_keygen(ot_otbn_vert: OTOTBNVERT, expected_key,
return share0, share1


def check_ciphertext_modinv(ot_otbn_vert: OTOTBNVERT, expected_output,
def check_ciphertext_modinv(ot_otbn_vert: OTOTBN, expected_output,
curve_cfg: CurveConfig):
""" Compares the received modular inverse output with the generated output.

Expand Down Expand Up @@ -524,7 +524,7 @@ def check_ciphertext_modinv(ot_otbn_vert: OTOTBNVERT, expected_output,
return actual_output


def capture_keygen(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBNVERT,
def capture_keygen(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBN,
capture_cfg: CaptureConfig, curve_cfg: CurveConfig,
project: SCAProject, target: Target):
""" Capture power consumption during selected OTBN operation.
Expand Down Expand Up @@ -602,7 +602,7 @@ def capture_keygen(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBNVERT,
pbar.update(capture_cfg.num_segments)


def capture_modinv(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBNVERT,
def capture_modinv(cfg: dict, scope: Scope, ot_otbn_vert: OTOTBN,
capture_cfg: CaptureConfig, curve_cfg: CurveConfig,
project: SCAProject, target: Target):
""" Capture power consumption during selected OTBN operation.
Expand Down
65 changes: 63 additions & 2 deletions target/communication/sca_otbn_commands.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,65 @@
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""Communication interface for the SHA3 SCA application on OpenTitan.
"""Communication interface for the OTBN SCA application on OpenTitan.

Communication with OpenTitan either happens over simpleserial or the uJson
command interface.
"""
import json
import time
from typing import Optional


class OTOTBNVERT:
class OTOTBN:
def __init__(self, target, protocol: str) -> None:
self.target = target
self.simple_serial = True
if protocol == "ujson":
self.simple_serial = False

def _ujson_otbn_sca_cmd(self):
# TODO: without the delay, the device uJSON command handler program
# does not recognize the commands. Tracked in issue #256.
time.sleep(0.01)
self.target.write(json.dumps("OtbnSca").encode("ascii"))

def init(self):
""" Initializes OTBN on the target.
Returns:
The device ID of the device.
"""
if not self.simple_serial:
# OtbnSca command.
self._ujson_otbn_sca_cmd()
# Init the OTBN core.
self.target.write(json.dumps("Init").encode("ascii"))
# Read back device ID from device.
return self.read_response(max_tries=30)

def init_keymgr(self):
""" Initializes the key manager for OTBN on the target.
"""
if not self.simple_serial:
# OtbnSca command.
self._ujson_otbn_sca_cmd()
# Init the key manager.
self.target.write(json.dumps("InitKeyMgr").encode("ascii"))

def key_sideload_fvsr(self, seed: int):
""" Starts the key sidloading FvsR test on OTBN.
Args:
seed: The fixed seed used by the key manager.
"""
if not self.simple_serial:
# OtbnSca command.
self._ujson_otbn_sca_cmd()
# Start the KeySideloadFvsr test.
self.target.write(json.dumps("KeySideloadFvsr").encode("ascii"))
time.sleep(0.01)
seed_data = {"fixed_seed": seed}
self.target.write(json.dumps(seed_data).encode("ascii"))

def choose_otbn_app(self, app):
""" Select the OTBN application.
Args:
Expand Down Expand Up @@ -105,3 +150,19 @@ def read_output(self, len_bytes):
"""
if self.simple_serial:
return self.target.read("r", len_bytes, ack=False)

def read_response(self, max_tries: Optional[int] = 1) -> str:
""" Read response from OTBN SCA framework.
Args:
max_tries: Maximum number of attempts to read from UART.

Returns:
The JSON response of OpenTitan.
"""
it = 0
while it != max_tries:
read_line = str(self.target.readline())
if "RESP_OK" in read_line:
return read_line.split("RESP_OK:")[1].split(" CRC:")[0]
it += 1
return ""
Loading