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

[pentest] Ibex SCA tests #22133

Merged
merged 1 commit into from
Mar 21, 2024
Merged
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
20 changes: 20 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,25 @@ cc_library(
],
)

cc_library(
name = "ibex_sca",
srcs = ["ibex_sca.c"],
hdrs = [
"ibex_sca.h",
"status.h",
],
deps = [
"//sw/device/lib/base:memory",
"//sw/device/lib/base:status",
"//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/crypto/cryptotest/firmware:sca_lib",
"//sw/device/tests/crypto/cryptotest/json:ibex_sca_commands",
],
)

cc_library(
name = "kmac_sca",
srcs = ["kmac_sca.c"],
Expand Down Expand Up @@ -301,6 +320,7 @@ FIRMWARE_DEPS = [
":hash",
":hmac",
":ibex_fi",
":ibex_sca",
":kmac_sca",
":kmac",
":otbn_fi",
Expand Down
5 changes: 5 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "sw/device/tests/crypto/cryptotest/json/hash_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/hmac_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/ibex_fi_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/ibex_sca_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/kmac_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/kmac_sca_commands.h"
#include "sw/device/tests/crypto/cryptotest/json/otbn_fi_commands.h"
Expand All @@ -36,6 +37,7 @@
#include "hash.h"
#include "hmac.h"
#include "ibex_fi.h"
#include "ibex_sca.h"
#include "kmac.h"
#include "kmac_sca.h"
#include "otbn_fi.h"
Expand Down Expand Up @@ -77,6 +79,9 @@ status_t process_cmd(ujson_t *uj) {
case kCryptotestCommandIbexFi:
RESP_ERR(uj, handle_ibex_fi(uj));
break;
case kCryptotestCommandIbexSca:
RESP_ERR(uj, handle_ibex_sca(uj));
break;
case kCryptotestCommandKmacSca:
RESP_ERR(uj, handle_kmac_sca(uj));
break;
Expand Down
238 changes: 238 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/ibex_sca.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "sw/device/tests/crypto/cryptotest/firmware/ibex_sca.h"

#include "sw/device/lib/base/memory.h"
#include "sw/device/lib/base/status.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/crypto/cryptotest/firmware/sca_lib.h"
#include "sw/device/tests/crypto/cryptotest/firmware/status.h"
#include "sw/device/tests/crypto/cryptotest/json/ibex_sca_commands.h"

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

// Buffer to allow the compiler to allocate a safe area in Main SRAM where
// we can do the write/read test without the risk of clobbering data
// used by the program.
OT_SECTION(".data")
static volatile uint32_t sram_main_buffer[8];

/**
* ibex.sca.tl_write
*
* This SCA penetration test executes the following instructions:
* - Loop num_iterations:
* - Set trigger
* - Write data over TL-UL into SRAM.
* - Unset trigger
*
* SCA traces are captured during trigger_high & trigger_low.
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca_tl_write(ujson_t *uj) {
// Get data to write into SRAM.
ibex_sca_test_data_t uj_data;
TRY(ujson_deserialize_ibex_sca_test_data_t(uj, &uj_data));

// Get address of buffer located in SRAM.
uintptr_t sram_main_buffer_addr = (uintptr_t)&sram_main_buffer;
mmio_region_t sram_region_main_addr =
mmio_region_from_addr(sram_main_buffer_addr);

// SCA code target.
for (int it = 0; it < uj_data.num_iterations; it++) {
sca_set_trigger_high();
// Write provided data into SRAM.
for (int i = 0; i < 8; i++) {
mmio_region_write32(sram_region_main_addr,
i * (ptrdiff_t)sizeof(uint32_t), uj_data.data[i]);
}
sca_set_trigger_low();
}

// Acknowledge test.
ibex_sca_result_t uj_output;
uj_output.result = 0;
RESP_OK(ujson_serialize_ibex_sca_result_t, uj, &uj_output);
return OK_STATUS(0);
}

/**
* ibex.sca.tl_read
*
* This SCA penetration test executes the following instructions:
* - Loop num_iterations:
* - Set trigger
* - Read data from SRAM over TL-UL.
* - Unset trigger
*
* SCA traces are captured during trigger_high & trigger_low.
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca_tl_read(ujson_t *uj) {
// Get data to write into SRAM.
ibex_sca_test_data_t uj_data;
TRY(ujson_deserialize_ibex_sca_test_data_t(uj, &uj_data));

// Get address of buffer located in SRAM.
uintptr_t sram_main_buffer_addr = (uintptr_t)&sram_main_buffer;
mmio_region_t sram_region_main_addr =
mmio_region_from_addr(sram_main_buffer_addr);

// Write provided data into SRAM.
for (int i = 0; i < 8; i++) {
mmio_region_write32(sram_region_main_addr, i * (ptrdiff_t)sizeof(uint32_t),
uj_data.data[i]);
}

uint32_t read_data[8];

// SCA code target.
for (int it = 0; it < uj_data.num_iterations; it++) {
sca_set_trigger_high();
// Fetch data from SRAM.
for (int i = 0; i < 8; i++) {
read_data[i] = mmio_region_read32(sram_region_main_addr,
i * (ptrdiff_t)sizeof(uint32_t));
}
sca_set_trigger_low();
}
// Acknowledge test.
ibex_sca_result_t uj_output;
uj_output.result = 0;
RESP_OK(ujson_serialize_ibex_sca_result_t, uj, &uj_output);
return OK_STATUS(0);
}

/**
* ibex.sca.register_file_write
*
* This SCA penetration test executes the following instructions:
* - Loop num_iterations:
* - Set trigger
* - Write provided data to registers in RF
* - Unset trigger
*
* SCA traces are captured during trigger_high & trigger_low.
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca_register_file_write(ujson_t *uj) {
// Get data to write into RF.
ibex_sca_test_data_t uj_data;
TRY(ujson_deserialize_ibex_sca_test_data_t(uj, &uj_data));
// SCA code target.
for (int it = 0; it < uj_data.num_iterations; it++) {
sca_set_trigger_high();
// Write provided data into register file.
asm volatile("mv x5, %0" : : "r"(uj_data.data[0]));
asm volatile("mv x6, %0" : : "r"(uj_data.data[1]));
asm volatile("mv x7, %0" : : "r"(uj_data.data[2]));
asm volatile("mv x28, %0" : : "r"(uj_data.data[3]));
asm volatile("mv x29, %0" : : "r"(uj_data.data[4]));
asm volatile("mv x30, %0" : : "r"(uj_data.data[5]));
asm volatile("mv x31, %0" : : "r"(uj_data.data[6]));
sca_set_trigger_low();
}
// Acknowledge test.
ibex_sca_result_t uj_output;
uj_output.result = 0;
RESP_OK(ujson_serialize_ibex_sca_result_t, uj, &uj_output);
return OK_STATUS(0);
}

/**
* ibex.sca.register_file_read
*
* This SCA penetration test executes the following instructions:
* - Loop num_iterations:
* - Set trigger
* - Read data from RF
* - Unset trigger
*
* SCA traces are captured during trigger_high & trigger_low.
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca_register_file_read(ujson_t *uj) {
// Get data to write into RF.
ibex_sca_test_data_t uj_data;
TRY(ujson_deserialize_ibex_sca_test_data_t(uj, &uj_data));
// Initialize temporary registers with reference values.
asm volatile("mv x5, %0" : : "r"(uj_data.data[0]));
asm volatile("mv x6, %0" : : "r"(uj_data.data[1]));
asm volatile("mv x7, %0" : : "r"(uj_data.data[2]));
asm volatile("mv x28, %0" : : "r"(uj_data.data[3]));
asm volatile("mv x29, %0" : : "r"(uj_data.data[4]));
asm volatile("mv x30, %0" : : "r"(uj_data.data[5]));

// SCA code target.
for (int it = 0; it < uj_data.num_iterations; it++) {
sca_set_trigger_high();
// Copy registers.
asm volatile("mv x28, x5");
asm volatile("mv x29, x6");
asm volatile("mv x30, x7");
sca_set_trigger_low();
}
// Acknowledge test.
ibex_sca_result_t uj_output;
uj_output.result = 0;
RESP_OK(ujson_serialize_ibex_sca_result_t, uj, &uj_output);
return OK_STATUS(0);
}

/**
* Initializes the Ibex SCA test.
*
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca_init(ujson_t *uj) {
// Setup trigger and enable peripherals needed for the test.
sca_select_trigger_type(kScaTriggerTypeSw);
// As we are using the software defined trigger, the first argument of
// sca_init is not needed. kScaTriggerSourceAes is selected as a placeholder.
sca_init(kScaTriggerSourceAes, kScaPeripheralIoDiv4);

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

return OK_STATUS(0);
}

/**
* Ibex SCA command handler.
*
* Command handler for the Ibex SCA command.
*
* @param uj The received uJSON data.
*/
status_t handle_ibex_sca(ujson_t *uj) {
ibex_sca_subcommand_t cmd;
TRY(ujson_deserialize_ibex_sca_subcommand_t(uj, &cmd));
switch (cmd) {
case kIbexScaSubcommandInit:
return handle_ibex_sca_init(uj);
case kIbexScaSubcommandRFRead:
return handle_ibex_sca_register_file_read(uj);
case kIbexScaSubcommandRFWrite:
return handle_ibex_sca_register_file_write(uj);
case kIbexScaSubcommandTLRead:
return handle_ibex_sca_tl_read(uj);
case kIbexScaSubcommandTLWrite:
return handle_ibex_sca_tl_write(uj);
default:
LOG_ERROR("Unrecognized IBEX SCA subcommand: %d", cmd);
return INVALID_ARGUMENT();
}
return OK_STATUS(0);
}
18 changes: 18 additions & 0 deletions sw/device/tests/crypto/cryptotest/firmware/ibex_sca.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_IBEX_SCA_H_
#define OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_IBEX_SCA_H_

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

status_t handle_ibex_sca_tl_write(ujson_t *uj);
status_t handle_ibex_sca_tl_read(ujson_t *uj);
status_t handle_ibex_sca_register_file_write(ujson_t *uj);
status_t handle_ibex_sca_register_file_read(ujson_t *uj);
status_t handle_ibex_sca_init(ujson_t *uj);
status_t handle_ibex_sca(ujson_t *uj);

#endif // OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_FIRMWARE_IBEX_SCA_H_
8 changes: 8 additions & 0 deletions sw/device/tests/crypto/cryptotest/json/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ cc_library(
":hash_commands",
":hmac_commands",
":ibex_fi_commands",
":ibex_sca_commands",
":kmac_commands",
":kmac_sca_commands",
":otbn_fi_commands",
Expand Down Expand Up @@ -90,6 +91,13 @@ cc_library(
deps = ["//sw/device/lib/ujson"],
)

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

cc_library(
name = "kmac_sca_commands",
srcs = ["kmac_sca_commands.c"],
Expand Down
1 change: 1 addition & 0 deletions sw/device/tests/crypto/cryptotest/json/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extern "C" {
value(_, Kmac) \
value(_, AesSca) \
value(_, IbexFi) \
value(_, IbexSca) \
value(_, KmacSca) \
value(_, OtbnFi) \
value(_, PrngSca) \
Expand Down
6 changes: 6 additions & 0 deletions sw/device/tests/crypto/cryptotest/json/ibex_sca_commands.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

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

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

// clang-format off

#define IBEXSCA_SUBCOMMAND(_, value) \
value(_, Init) \
value(_, RFRead) \
value(_, RFWrite) \
value(_, TLRead) \
value(_, TLWrite)
UJSON_SERDE_ENUM(IbexScaSubcommand, ibex_sca_subcommand_t, IBEXSCA_SUBCOMMAND);

#define IBEXSCA_TEST_DATA(field, string) \
field(num_iterations, uint32_t) \
field(data, uint32_t, 8)
UJSON_SERDE_STRUCT(IbexScaTestData, ibex_sca_test_data_t, IBEXSCA_TEST_DATA);

#define IBEXSCA_RESULT(field, string) \
field(result, uint32_t)
UJSON_SERDE_STRUCT(IbexScaResult, ibex_sca_result_t, IBEXSCA_RESULT);

// clang-format on

#ifdef __cplusplus
}
#endif
#endif // OPENTITAN_SW_DEVICE_TESTS_CRYPTO_CRYPTOTEST_JSON_IBEX_SCA_COMMANDS_H_
Loading