Software APIs
otbn_randomness_impl.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/tests/otbn_randomness_impl.h"
6 
11 #include "sw/device/lib/testing/test_framework/check.h"
12 
13 OTBN_DECLARE_APP_SYMBOLS(randomness);
14 OTBN_DECLARE_SYMBOL_ADDR(randomness, iterations);
15 OTBN_DECLARE_SYMBOL_ADDR(randomness, rv);
16 OTBN_DECLARE_SYMBOL_ADDR(randomness, fail_idx);
17 OTBN_DECLARE_SYMBOL_ADDR(randomness, rnd_out);
18 OTBN_DECLARE_SYMBOL_ADDR(randomness, urnd_out);
19 
20 static const otbn_app_t kOtbnAppRandomnessApp = OTBN_APP_T_INIT(randomness);
21 static const otbn_addr_t kVarIters = OTBN_ADDR_T_INIT(randomness, iterations);
22 static const otbn_addr_t kVarRv = OTBN_ADDR_T_INIT(randomness, rv);
23 static const otbn_addr_t kVarFailIdx = OTBN_ADDR_T_INIT(randomness, fail_idx);
24 static const otbn_addr_t kVarRndOut = OTBN_ADDR_T_INIT(randomness, rnd_out);
25 static const otbn_addr_t kVarUrndOut = OTBN_ADDR_T_INIT(randomness, urnd_out);
26 
27 /**
28  * LOG_INFO with a 256b unsigned integer as hexadecimal number with a prefix.
29  */
30 static void print_uint256(dif_otbn_t *otbn, const otbn_addr_t var,
31  const char *prefix) {
32  uint32_t data[32 / sizeof(uint32_t)];
33  CHECK_STATUS_OK(otbn_testutils_read_data(otbn, /*len_bytes=*/32, var, &data));
34  LOG_INFO("%s0x%08x%08x%08x%08x%08x%08x%08x%08x", prefix, data[7], data[6],
35  data[5], data[4], data[3], data[2], data[1], data[0]);
36 }
37 
38 void otbn_randomness_test_start(dif_otbn_t *otbn, uint32_t iters) {
39  otbn_randomness_test_prepare(otbn, iters);
40  CHECK_STATUS_OK(otbn_testutils_execute(otbn));
41 }
42 
43 void otbn_randomness_test_prepare(dif_otbn_t *otbn, uint32_t iters) {
44  // Reset the `kVarRv` value to ensure the result loaded by
45  // `otbn_randomness_test_end()` is the one generated by OTBN.
46  uint32_t rv = UINT32_MAX;
47  CHECK_STATUS_OK(
48  otbn_testutils_write_data(otbn, sizeof(uint32_t), &rv, kVarRv));
49  CHECK_STATUS_OK(otbn_testutils_load_app(otbn, kOtbnAppRandomnessApp));
50  CHECK_STATUS_OK(
51  otbn_testutils_write_data(otbn, sizeof(uint32_t), &iters, kVarIters));
52 }
53 
54 bool otbn_randomness_test_end(dif_otbn_t *otbn, bool skip_otbn_done_check) {
55  if (!skip_otbn_done_check) {
56  CHECK_STATUS_OK(otbn_testutils_wait_for_done(otbn, kDifOtbnErrBitsNoError));
57  }
58  uint32_t rv;
59  CHECK_STATUS_OK(otbn_testutils_read_data(otbn, /*len_bytes=*/4, kVarRv, &rv));
60  if (rv != 0) {
61  uint32_t fail_idx;
62  CHECK_STATUS_OK(otbn_testutils_read_data(otbn, /*len_bytes=*/4, kVarFailIdx,
63  &fail_idx));
64  LOG_ERROR("ERROR: Test with index %d failed.", fail_idx);
65  return false;
66  }
67  return true;
68 }
69 
70 void otbn_randomness_test_log_results(dif_otbn_t *otbn) {
71  print_uint256(otbn, kVarRndOut, "rnd = ");
72  print_uint256(otbn, kVarUrndOut, "urnd = ");
73 }