Skip to content

Commit

Permalink
[pentest] Add ROM FI tests
Browse files Browse the repository at this point in the history
This commit pulls over the ROM read digest FI test from the
pentest branch of nasahlpa/opentitan that has been used for
the penetration testing.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa authored and andreaskurth committed Sep 3, 2024
1 parent 4ec5ee8 commit bd6f0f9
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sw/device/tests/penetrationtests/firmware/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ FIRMWARE_DEPS_FPGA = [
"//sw/device/tests/penetrationtests/firmware/fi:ibex_fi",
"//sw/device/tests/penetrationtests/firmware/fi:otbn_fi",
"//sw/device/tests/penetrationtests/firmware/fi:rng_fi",
"//sw/device/tests/penetrationtests/firmware/fi:rom_fi",
"//sw/device/tests/penetrationtests/firmware/sca:aes_sca",
"//sw/device/tests/penetrationtests/firmware/sca:ibex_sca",
"//sw/device/tests/penetrationtests/firmware/sca:kmac_sca",
Expand All @@ -40,6 +41,7 @@ FIRMWARE_DEPS_FI = [
"//sw/device/tests/penetrationtests/firmware/fi:ibex_fi",
"//sw/device/tests/penetrationtests/firmware/fi:otbn_fi",
"//sw/device/tests/penetrationtests/firmware/fi:rng_fi",
"//sw/device/tests/penetrationtests/firmware/fi:rom_fi",
"//sw/device/tests/penetrationtests/firmware/lib:extclk_sca_fi",
"//sw/device/lib/base:csr",
"//sw/device/lib/base:status",
Expand Down
20 changes: 20 additions & 0 deletions sw/device/tests/penetrationtests/firmware/fi/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,23 @@ cc_library(
"//sw/device/tests/penetrationtests/json:rng_fi_commands",
],
)

cc_library(
name = "rom_fi",
srcs = ["rom_fi.c"],
hdrs = ["rom_fi.h"],
deps = [
"//hw/ip/rom_ctrl/data:rom_ctrl_c_regs",
"//sw/device/lib/base:abs_mmio",
"//sw/device/lib/base:memory",
"//sw/device/lib/base:status",
"//sw/device/lib/dif:rom_ctrl",
"//sw/device/lib/dif:rv_core_ibex",
"//sw/device/lib/runtime:log",
"//sw/device/lib/testing/test_framework:ujson_ottf",
"//sw/device/lib/ujson",
"//sw/device/sca/lib:sca",
"//sw/device/tests/penetrationtests/firmware/lib:sca_lib",
"//sw/device/tests/penetrationtests/json:rom_fi_commands",
],
)
122 changes: 122 additions & 0 deletions sw/device/tests/penetrationtests/firmware/fi/rom_fi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/tests/penetrationtests/firmware/fi/rom_fi.h"

#include "sw/device/lib/base/abs_mmio.h"
#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/status.h"
#include "sw/device/lib/dif/dif_rom_ctrl.h"
#include "sw/device/lib/dif/dif_rv_core_ibex.h"
#include "sw/device/lib/runtime/log.h"
#include "sw/device/lib/testing/test_framework/ottf_test_config.h"
#include "sw/device/lib/testing/test_framework/ujson_ottf.h"
#include "sw/device/lib/ujson/ujson.h"
#include "sw/device/sca/lib/sca.h"
#include "sw/device/tests/penetrationtests/firmware/lib/sca_lib.h"
#include "sw/device/tests/penetrationtests/json/rom_fi_commands.h"

#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "rom_ctrl_regs.h"

// NOP macros.
#define NOP1 "addi x0, x0, 0\n"
#define NOP10 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1 NOP1
#define NOP30 NOP10 NOP10 NOP10

// Interface to Ibex.
static dif_rv_core_ibex_t rv_core_ibex;

static dif_rom_ctrl_t rom_ctrl;

status_t handle_rom_read(ujson_t *uj) {
sca_registered_alerts_t reg_alerts = sca_get_triggered_alerts();

dif_rom_ctrl_digest_t expected_digest;
dif_rom_ctrl_digest_t fi_digest[8];
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &expected_digest));

sca_set_trigger_high();
asm volatile(NOP30);
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[0]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[1]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[2]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[3]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[4]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[5]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[6]));
TRY(dif_rom_ctrl_get_digest(&rom_ctrl, &fi_digest[7]));
asm volatile(NOP30);
sca_set_trigger_low();

// Get registered alerts from alert handler.
reg_alerts = sca_get_triggered_alerts();

// Read ERR_STATUS register.
dif_rv_core_ibex_error_status_t codes;
TRY(dif_rv_core_ibex_get_error_status(&rv_core_ibex, &codes));

rom_fi_digest_t uj_output;
memset(uj_output.digest, 0, sizeof(uj_output.digest));
for (size_t i = 0; i < 8; i++) {
if (memcmp(&expected_digest, &fi_digest[i],
ROM_CTRL_DIGEST_MULTIREG_COUNT)) {
uj_output.digest[i] =
fi_digest[i]
.digest[0]; // Just return the first 32-bit of the digest.
}
}

// Send the first 8 bytes of the digest and the alerts back to the host.
uj_output.err_status = codes;
memcpy(uj_output.alerts, reg_alerts.alerts, sizeof(reg_alerts.alerts));
RESP_OK(ujson_serialize_rom_fi_digest_t, uj, &uj_output);
return OK_STATUS();
}

status_t handle_rom_fi_init(ujson_t *uj) {
sca_select_trigger_type(kScaTriggerTypeSw);
sca_init(kScaTriggerSourceAes,
kScaPeripheralIoDiv4 | kScaPeripheralEdn | kScaPeripheralCsrng |
kScaPeripheralEntropy | kScaPeripheralKmac);

// Configure the alert handler. Alerts triggered by IP blocks are captured
// and reported to the test.
sca_configure_alert_handler();

// Disable the instruction cache and dummy instructions for FI attacks.
sca_configure_cpu();

// Initialize rom_ctrl.
mmio_region_t rom_ctrl_reg =
mmio_region_from_addr(TOP_EARLGREY_ROM_CTRL_REGS_BASE_ADDR);
TRY(dif_rom_ctrl_init(rom_ctrl_reg, &rom_ctrl));

// Configure Ibex to allow reading ERR_STATUS register.
TRY(dif_rv_core_ibex_init(
mmio_region_from_addr(TOP_EARLGREY_RV_CORE_IBEX_CFG_BASE_ADDR),
&rv_core_ibex));

// Read device ID and return to host.
penetrationtest_device_id_t uj_output;
TRY(sca_read_device_id(uj_output.device_id));
RESP_OK(ujson_serialize_penetrationtest_device_id_t, uj, &uj_output);

return OK_STATUS();
}

status_t handle_rom_fi(ujson_t *uj) {
rom_fi_subcommand_t cmd;
TRY(ujson_deserialize_rom_fi_subcommand_t(uj, &cmd));
switch (cmd) {
case kRomFiSubcommandInit:
return handle_rom_fi_init(uj);
case kRomFiSubcommandRead:
return handle_rom_read(uj);
default:
LOG_ERROR("Unrecognized Rom FI subcommand: %d", cmd);
return INVALID_ARGUMENT();
}
return OK_STATUS();
}
39 changes: 39 additions & 0 deletions sw/device/tests/penetrationtests/firmware/fi/rom_fi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_FIRMWARE_FI_ROM_FI_H_
#define OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_FIRMWARE_FI_ROM_FI_H_

#include "sw/device/lib/base/status.h"
#include "sw/device/lib/ujson/ujson.h"

/**
* ROM read FI test.
*
* Read the ROM digest while injecting faults.
*
* @param uj An initialized uJSON context.
* @return OK or error.
*/
status_t handle_rom_fi_init(ujson_t *uj);

/**
* Initializes the trigger and configures the device for the Rom FI test.
*
* @param uj An initialized uJSON context.
* @return OK or error.
*/
status_t handle_rom_fi_init(ujson_t *uj);

/**
* Rom FI command handler.
*
* Command handler for the Rom FI command.
*
* @param uj An initialized uJSON context.
* @return OK or error.
*/
status_t handle_rom_fi(ujson_t *uj);

#endif // OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_FIRMWARE_FI_ROM_FI_H_
5 changes: 5 additions & 0 deletions sw/device/tests/penetrationtests/firmware/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "sw/device/tests/penetrationtests/json/otbn_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/prng_sca_commands.h"
#include "sw/device/tests/penetrationtests/json/rng_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/rom_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/sha3_sca_commands.h"
#include "sw/device/tests/penetrationtests/json/trigger_sca_commands.h"

Expand All @@ -29,6 +30,7 @@
#include "fi/ibex_fi.h"
#include "fi/otbn_fi.h"
#include "fi/rng_fi.h"
#include "fi/rom_fi.h"
#include "lib/extclk_sca_fi.h"
#include "sca/aes_sca.h"
#include "sca/ibex_sca.h"
Expand Down Expand Up @@ -71,6 +73,9 @@ status_t process_cmd(ujson_t *uj) {
case kPenetrationtestCommandRngFi:
RESP_ERR(uj, handle_rng_fi(uj));
break;
case kPenetrationtestCommandRomFi:
RESP_ERR(uj, handle_rom_fi(uj));
break;
case kPenetrationtestCommandSha3Sca:
RESP_ERR(uj, handle_sha3_sca(uj));
break;
Expand Down
5 changes: 5 additions & 0 deletions sw/device/tests/penetrationtests/firmware/firmware_fi.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
#include "sw/device/tests/penetrationtests/json/ibex_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/otbn_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/rng_fi_commands.h"
#include "sw/device/tests/penetrationtests/json/rom_fi_commands.h"

// Include handlers
#include "fi/crypto_fi.h"
#include "fi/ibex_fi.h"
#include "fi/otbn_fi.h"
#include "fi/rng_fi.h"
#include "fi/rom_fi.h"
#include "lib/extclk_sca_fi.h"

OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
Expand All @@ -46,6 +48,9 @@ status_t process_cmd(ujson_t *uj) {
case kPenetrationtestCommandRngFi:
RESP_ERR(uj, handle_rng_fi(uj));
break;
case kPenetrationtestCommandRomFi:
RESP_ERR(uj, handle_rom_fi(uj));
break;
default:
LOG_ERROR("Unrecognized command: %d", cmd);
RESP_ERR(uj, INVALID_ARGUMENT());
Expand Down
8 changes: 8 additions & 0 deletions sw/device/tests/penetrationtests/json/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cc_library(
":kmac_sca_commands",
":otbn_fi_commands",
":prng_sca_commands",
":rom_fi_commands",
":sha3_sca_commands",
":trigger_sca_commands",
"//sw/device/lib/ujson",
Expand Down Expand Up @@ -85,6 +86,13 @@ cc_library(
deps = ["//sw/device/lib/ujson"],
)

cc_library(
name = "rom_fi_commands",
srcs = ["rom_fi_commands.c"],
hdrs = ["rom_fi_commands.h"],
deps = ["//sw/device/lib/ujson"],
)

cc_library(
name = "sca_lib_commands",
srcs = ["sca_lib_commands.c"],
Expand Down
1 change: 1 addition & 0 deletions sw/device/tests/penetrationtests/json/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern "C" {
value(_, OtbnFi) \
value(_, PrngSca) \
value(_, RngFi) \
value(_, RomFi) \
value(_, Sha3Sca) \
value(_, TriggerSca)
UJSON_SERDE_ENUM(PenetrationtestCommand, penetrationtest_cmd_t, COMMAND);
Expand Down
6 changes: 6 additions & 0 deletions sw/device/tests/penetrationtests/json/rom_fi_commands.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#define UJSON_SERDE_IMPL 1
#include "rom_fi_commands.h"
31 changes: 31 additions & 0 deletions sw/device/tests/penetrationtests/json/rom_fi_commands.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_JSON_ROM_FI_COMMANDS_H_
#define OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_JSON_ROM_FI_COMMANDS_H_
#include "sw/device/lib/ujson/ujson_derive.h"
#ifdef __cplusplus
extern "C" {
#endif

// clang-format off

#define ROMFI_SUBCOMMAND(_, value) \
value(_, Init) \
value(_, Read)
UJSON_SERDE_ENUM(RomFiSubcommand, rom_fi_subcommand_t, ROMFI_SUBCOMMAND);


#define ROMFI_DIGEST(field, string) \
field(digest, uint32_t, 8) \
field(alerts, uint32_t, 3) \
field(err_status, uint32_t)
UJSON_SERDE_STRUCT(RomFiDigest, rom_fi_digest_t, ROMFI_DIGEST);

// clang-format on

#ifdef __cplusplus
}
#endif
#endif // OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_JSON_ROM_FI_COMMANDS_H_

0 comments on commit bd6f0f9

Please sign in to comment.