7 #include "sw/device/lib/runtime/irq.h"
9 #include "sw/device/lib/testing/entropy_testutils.h"
11 #include "sw/device/lib/testing/profile.h"
12 #include "sw/device/lib/testing/rv_plic_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
68 OTTF_DEFINE_TEST_CONFIG();
73 static dif_rv_plic_t plic;
78 static dif_otbn_t otbn;
93 static volatile dif_otbn_irq_t irq;
107 void ottf_external_isr(uint32_t *exc_info) {
114 irq = (dif_otbn_irq_t)(irq_id -
117 CHECK_DIF_OK(dif_otbn_irq_acknowledge(&otbn, irq));
125 static void otbn_wait_for_done_irq(dif_otbn_t *otbn) {
130 plic_peripheral = UINT32_MAX;
137 ATOMIC_WAIT_FOR_INTERRUPT(plic_peripheral != UINT32_MAX);
140 "Interrupt from incorrect peripheral: (exp: %d, obs: %s)",
151 CHECK_DIF_OK(dif_otbn_irq_acknowledge(otbn, kDifOtbnIrqDone));
154 static void otbn_init_irq(
void) {
158 CHECK_DIF_OK(dif_rv_plic_init(plic_base_addr, &plic));
172 irq_global_ctrl(
true);
173 irq_external_ctrl(
true);
181 static void otbn_wipe_dmem(dif_otbn_t *otbn) {
183 otbn_wait_for_done_irq(otbn);
193 static void check_data(
const char *msg,
const uint8_t *actual,
194 const uint8_t *expected,
size_t size_bytes) {
195 for (
int i = 0; i < size_bytes; ++i) {
196 CHECK(actual[i] == expected[i],
197 "%s: mismatch at byte %d: 0x%x (actual) != 0x%x (expected)", msg, i,
198 actual[i], expected[i]);
213 static void p256_ecdsa_sign(dif_otbn_t *otbn,
const uint8_t *msg,
214 const uint8_t *private_key_d, uint8_t *signature_r,
215 uint8_t *signature_s) {
219 uint32_t mode = kModeSign;
225 private_key_d, kOtbnVarD0));
228 uint8_t d0_high[32] = {0};
233 uint8_t d1[64] = {0};
239 otbn_wait_for_done_irq(otbn);
260 static void p256_ecdsa_verify(dif_otbn_t *otbn,
const uint8_t *msg,
261 const uint8_t *signature_r,
262 const uint8_t *signature_s,
263 const uint8_t *public_key_x,
264 const uint8_t *public_key_y,
265 uint8_t *signature_x_r) {
269 uint32_t mode = kModeVerify;
279 public_key_x, kOtbnVarX));
281 public_key_y, kOtbnVarY));
285 otbn_wait_for_done_irq(otbn);
297 static void test_ecdsa_p256_roundtrip(
void) {
299 static const uint8_t kIn[32] = {
"Hello OTBN."};
302 static const uint8_t kPublicKeyQx[32] = {
303 0x4e, 0xb2, 0x8b, 0x55, 0xeb, 0x88, 0x62, 0x24, 0xf2, 0xbf, 0x1b,
304 0x9e, 0xd8, 0x4a, 0x09, 0xa7, 0x86, 0x67, 0x92, 0xcd, 0xca, 0x07,
305 0x5d, 0x07, 0x82, 0xe7, 0x2d, 0xac, 0x31, 0x14, 0x79, 0x1f};
308 static const uint8_t kPublicKeyQy[32] = {
309 0x27, 0x9c, 0xe4, 0x23, 0x24, 0x10, 0xa2, 0xfa, 0xbd, 0x53, 0x73,
310 0xf1, 0xa5, 0x08, 0xf0, 0x40, 0x9e, 0xc0, 0x55, 0x21, 0xa4, 0xf0,
311 0x54, 0x59, 0x00, 0x3e, 0x5f, 0x15, 0x3c, 0xc6, 0x4b, 0x87};
314 static const uint8_t kPrivateKeyD[32] = {
315 0xcd, 0xb4, 0x57, 0xaf, 0x1c, 0x9f, 0x4c, 0x74, 0x02, 0x0c, 0x7e,
316 0x8b, 0xe9, 0x93, 0x3e, 0x28, 0x0c, 0xf0, 0x18, 0x0d, 0xf4, 0x6c,
317 0x0b, 0xda, 0x7a, 0xbb, 0xe6, 0x8f, 0xb7, 0xa0, 0x45, 0x55};
320 uint64_t t_start_init = profile_start();
325 profile_end_and_print(t_start_init,
"Initialization");
328 uint8_t signature_r[32] = {0};
329 uint8_t signature_s[32] = {0};
332 uint64_t t_start_sign = profile_start();
333 p256_ecdsa_sign(&otbn, kIn, kPrivateKeyD, signature_r, signature_s);
334 profile_end_and_print(t_start_sign,
"Sign");
337 LOG_INFO(
"Wiping OTBN DMEM and reloading app");
338 otbn_wipe_dmem(&otbn);
342 uint8_t signature_x_r[32] = {0};
345 uint64_t t_start_verify = profile_start();
346 p256_ecdsa_verify(&otbn, kIn, signature_r, signature_s, kPublicKeyQx,
347 kPublicKeyQy, signature_x_r);
352 check_data(
"signature_x_r", signature_r, signature_x_r, 32);
353 profile_end_and_print(t_start_verify,
"Verify");
357 otbn_wipe_dmem(&otbn);
361 CHECK_STATUS_OK(entropy_testutils_auto_mode_init());
363 test_ecdsa_p256_roundtrip();