Skip to content

Commit

Permalink
Add app for testing RNG
Browse files Browse the repository at this point in the history
The test app hexdumps RNG outputs, this can be converted back into
binary form and fed into rngtest.
  • Loading branch information
arturkow2000 committed Apr 2, 2024
1 parent b0203a7 commit bdcdb15
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 1 deletion.
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ target_sources(app PRIVATE
src/tpm/plat/run_command.c
src/tpm/plat/unique.c
src/tpm/init.c
src/rng.c
)
target_include_directories(app PRIVATE include)
target_link_libraries(app PRIVATE ms-tpm-20-ref)
Expand Down
4 changes: 4 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ config TWPM_EMULATED_NV_SIZE
default 16384
depends on TWPM_NV_EMULATE

config TWPM_RNG_TEST
bool "Enable RNG (Random Number Generator) test"
default false

source "Kconfig.zephyr"
21 changes: 20 additions & 1 deletion app/boards/riscv/orangecrab/orangecrab_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,24 @@ CONFIG_BOARD_ORANGECRAB=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_XIP=n

# Workaround for misbehaving UART and mtimer drivers.
# Force sync for both printk and log, we have some problems with task scheduling
# (see mtimer problem described below) which cause messages to be delayed for
# too long and then dropped due to buffer overflow.
CONFIG_PRINTK_SYNC=y
CONFIG_LOG_MODE_MINIMAL=y
# Broken, TX randomly hangs.
CONFIG_UART_INTERRUPT_DRIVEN=n

# FIXME: Seems like there is something wrong with mtimer driver. Zephyr should
# translate hardware clock cycles into to ticks which is Zephyr's representation
# of time, but something bad happens causing Zephyr to hang for indefinitely
# long when sleeping even for 1 ms. As workaround set SYS_CLOCK_TICKS_PER_SEC
# to equal SYS_CLOCK_HW_CYCLES_PER_SEC. This allows Zephyr to proceed.
#
# Note: SYS_CLOCK_HW_CYCLES_PER_SEC is set from DTS
# See SYS_CLOCK_HW_CYCLES_PER_SEC and CONFIG_SYS_CLOCK_TICKS_PER_SEC help for
# details.
CONFIG_SYS_CLOCK_TICKS_PER_SEC=50000000
15 changes: 15 additions & 0 deletions app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ struct k_thread tpm_thread;
k_tid_t tpm_thread_id;
K_SEM_DEFINE(tpm_cmd_sem, 0, 1);

#ifdef CONFIG_TWPM_RNG_TEST
K_THREAD_STACK_DEFINE(rng_thread_stack, 512);
struct k_thread rng_thread;
#endif

static uint8_t tpm_cmd[2048];
static uint32_t tpm_cmd_size = 0;

Expand Down Expand Up @@ -99,6 +104,10 @@ static void twpm_isr(const struct device *const dev)
}
}

#ifdef CONFIG_TWPM_RNG_TEST
extern void twpm_test_rng();
#endif

int main(void)
{
LOG_INF("Starting TwPM");
Expand All @@ -114,5 +123,11 @@ int main(void)
tpm_thread_entry, NULL, NULL, NULL, 5, 0,
K_NO_WAIT);

#ifdef CONFIG_TWPM_RNG_TEST
k_thread_create(&rng_thread, rng_thread_stack,
K_THREAD_STACK_SIZEOF(rng_thread_stack), twpm_test_rng,
NULL, NULL, NULL, 5, 0, K_NO_WAIT);
#endif

return 0;
}
106 changes: 106 additions & 0 deletions app/src/rng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
#include <zephyr/random/random.h>
#include <assert.h>

#ifdef CONFIG_TWPM_RNG_TEST
static uint8_t buffer[64];
char buffer_ascii[sizeof buffer * 2 + 1];

static int rng_test(const struct shell *sh) {
int ret = sys_csrand_get(buffer, sizeof buffer);
if (ret == 0) {
for (int i = 0; i < sizeof buffer; i++) {
uint8_t t;

t = buffer[i] >> 4;
buffer_ascii[i * 2] = t < 10 ? t + '0' : t + 'a' - 10;

t = buffer[i] & 0x0f;
buffer_ascii[i * 2 + 1] = t < 10 ? t + '0' : t + 'a' - 10;
}

buffer_ascii[sizeof buffer_ascii - 1] = '\0';

if (sh)
shell_print(sh, "%s", buffer_ascii);
else
printk("%s\n", buffer_ascii);
} else {
if (sh)
shell_error(sh, "RNG error %d", ret);
else
printk("RNG error %d\n", ret);
}

return ret;
}

void twpm_test_rng() {
while (true) {
int ret = rng_test(NULL);
if (ret < 0) {
printk("RNG test fail");
k_panic();
}

k_yield();
}
}

#ifdef CONFIG_SHELL
static const struct shell *shell;
static struct k_work_delayable work;

static void rng_work(struct k_work *_work) {
ARG_UNUSED(_work);

assert(shell != NULL);

int ret = rng_test(shell);

if (ret < 0) {
k_work_cancel_delayable(&work);
shell_set_bypass(shell, NULL);
shell = NULL;
} else
k_work_reschedule(&work, K_NO_WAIT);
}

static void rng_bypass(const struct shell *sh, uint8_t *data, size_t len) {
assert(shell != NULL);
assert(shell == sh);

for (size_t i = 0; i < len; i++) {
if (data[i] == 0x03) {
k_work_cancel_delayable(&work);
shell_set_bypass(shell, NULL);
shell = NULL;
break;
}
}

}

static int cmd_rng_test(const struct shell *sh, size_t argc, char *argv[])
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);

shell = sh;
k_work_init_delayable(&work, rng_work);
shell_set_bypass(sh, rng_bypass);
k_work_reschedule(&work, K_NO_WAIT);

return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(rng_commands,
SHELL_CMD(test, NULL, "Run RNG test", cmd_rng_test),
SHELL_SUBCMD_SET_END
);
SHELL_CMD_REGISTER(rng, &rng_commands, "RNG (Random Number Generator) commands", NULL);

#endif
#endif

0 comments on commit bdcdb15

Please sign in to comment.