5 #include "sw/device/tests/penetrationtests/firmware/sca/otbn_sca.h"
7 #include "ecc256_keygen_sca.h"
10 #include "sw/device/lib/base/status.h"
11 #include "sw/device/lib/crypto/drivers/keymgr.h"
12 #include "sw/device/lib/crypto/impl/keyblob.h"
13 #include "sw/device/lib/crypto/impl/status.h"
16 #include "sw/device/lib/testing/entropy_testutils.h"
17 #include "sw/device/lib/testing/keymgr_testutils.h"
18 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
19 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
20 #include "sw/device/lib/ujson/ujson.h"
22 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
23 #include "sw/device/tests/penetrationtests/json/otbn_sca_commands.h"
26 #include "otbn_regs.h"
28 static dif_otbn_t otbn;
29 static dif_keymgr_t keymgr;
30 static dif_kmac_t kmac;
33 kKeySideloadNumIt = 16,
38 kEcc256NumBytes = 256 / 8,
43 kEcc256NumWords = kEcc256NumBytes /
sizeof(uint32_t),
47 kNumBatchOpsMax = 256,
60 static const otbn_addr_t kOtbnAppKeySideloadks0l =
62 static const otbn_addr_t kOtbnAppKeySideloadks0h =
64 static const otbn_addr_t kOtbnAppKeySideloadks1l =
66 static const otbn_addr_t kOtbnAppKeySideloadks1h =
68 static const otbn_addr_t kOtbnAppKeySideloadkl =
70 static const otbn_addr_t kOtbnAppKeySideloadkh =
85 static const otbn_addr_t kOtbnVarRsaModulus =
OTBN_ADDR_T_INIT(rsa, modulus);
105 static const otbn_addr_t kOtbnVarMode =
OTBN_ADDR_T_INIT(p256_ecdsa_sca, mode);
106 static const otbn_addr_t kOtbnVarMsg =
OTBN_ADDR_T_INIT(p256_ecdsa_sca, msg);
121 TRY(otbn_dmem_sec_wipe());
122 TRY(otbn_imem_sec_wipe());
137 void gen_mask_data(uint32_t *dest_array,
bool mask_en,
size_t len) {
139 for (
size_t j = 0; j < len; ++j) {
143 memset(dest_array, 0, len *
sizeof(dest_array[0]));
158 void gen_fvsr_data(uint32_t *dest_array,
bool fixed, uint32_t *src_fixed_array,
161 memcpy(dest_array, src_fixed_array, len *
sizeof(src_fixed_array[0]));
163 for (
size_t j = 0; j < len; ++j) {
185 static status_t p256_ecdsa_sign(
const uint32_t *msg,
186 const uint32_t *private_key_d,
187 uint32_t *signature_r, uint32_t *signature_s,
191 TRY(otbn_dmem_write(1, &mode, kOtbnVarMode));
193 TRY(otbn_dmem_write(kEcc256NumWords, msg, kOtbnVarMsg));
195 TRY(otbn_dmem_write(kEcc256NumWords, private_key_d, kOtbnVarD0));
196 TRY(otbn_dmem_write(kEcc256NumWords, private_key_d + kEcc256NumWords,
199 TRY(otbn_dmem_write(kEcc256NumWords, k, kOtbnVarK0));
200 TRY(otbn_dmem_write(kEcc256NumWords, k + kEcc256NumWords, kOtbnVarK1));
203 pentest_set_trigger_high();
207 otbn_busy_wait_for_done();
208 pentest_set_trigger_low();
211 TRY(otbn_dmem_read(kEcc256NumWords, kOtbnVarR, signature_r));
212 TRY(otbn_dmem_read(kEcc256NumWords, kOtbnVarS, signature_s));
219 penetrationtest_otbn_sca_en_masks_t uj_data_masks;
222 penetrationtest_otbn_sca_ecdsa_p256_sign_t uj_data;
223 TRY(ujson_deserialize_penetrationtest_otbn_sca_ecdsa_p256_sign_t(uj,
227 uint32_t ecc256_private_key_d1[kEcc256NumWords];
228 memset(ecc256_private_key_d1, 0,
sizeof(ecc256_private_key_d1));
230 if (uj_data_masks.en_masks) {
231 for (
size_t j = 0; j < kEcc256NumWords; j++) {
237 uint32_t ecc256_secret_k1[kEcc256NumWords];
238 memset(ecc256_secret_k1, 0,
sizeof(ecc256_secret_k1));
240 if (uj_data_masks.en_masks) {
241 for (
size_t j = 0; j < kEcc256NumWords; j++) {
247 uint32_t ecc256_private_key_d[2 * kEcc256NumWords];
248 memset(ecc256_private_key_d, 0,
sizeof(ecc256_private_key_d));
249 memcpy(ecc256_private_key_d, uj_data.d0,
sizeof(uj_data.d0));
250 memcpy(ecc256_private_key_d + kEcc256NumWords, ecc256_private_key_d1,
251 sizeof(ecc256_private_key_d1));
254 uint32_t ecc256_secret_k[2 * kEcc256NumWords];
255 memset(ecc256_secret_k, 0,
sizeof(ecc256_secret_k));
256 memcpy(ecc256_secret_k, uj_data.k0,
sizeof(uj_data.k0));
257 memcpy(ecc256_secret_k + kEcc256NumWords, ecc256_secret_k1,
258 sizeof(ecc256_secret_k1));
260 otbn_load_app(kOtbnAppP256Ecdsa);
263 uint32_t ecc256_signature_r[kEcc256NumWords];
264 uint32_t ecc256_signature_s[kEcc256NumWords];
267 p256_ecdsa_sign(uj_data.msg, ecc256_private_key_d, ecc256_signature_r,
268 ecc256_signature_s, ecc256_secret_k);
271 penetrationtest_otbn_sca_ecdsa_p256_signature_t uj_output;
272 memcpy(uj_output.r, ecc256_signature_r,
sizeof(ecc256_signature_r));
273 memcpy(uj_output.s, ecc256_signature_s,
sizeof(ecc256_signature_s));
274 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_ecdsa_p256_signature_t, uj,
285 penetrationtest_otbn_sca_num_traces_t uj_data_num_traces;
286 TRY(ujson_deserialize_penetrationtest_otbn_sca_num_traces_t(
287 uj, &uj_data_num_traces));
289 if (uj_data_num_traces.num_traces > kNumBatchOpsMax) {
290 return OUT_OF_RANGE();
294 penetrationtest_otbn_sca_en_masks_t uj_data_masks;
295 TRY(ujson_deserialize_penetrationtest_otbn_sca_en_masks_t(uj,
299 uint32_t ecc256_message_batch[kNumBatchOpsMax][kEcc256NumWords];
301 uint32_t ecc256_private_key_d0_batch[kNumBatchOpsMax][kEcc256NumWords];
302 uint32_t ecc256_private_key_d1_batch[kNumBatchOpsMax][kEcc256NumWords];
303 uint32_t ecc256_private_key_d_batch[kNumBatchOpsMax][2 * kEcc256NumWords];
305 uint32_t ecc256_secret_key_k0_batch[kNumBatchOpsMax][kEcc256NumWords];
306 uint32_t ecc256_secret_key_k1_batch[kNumBatchOpsMax][kEcc256NumWords];
307 uint32_t ecc256_secret_key_k_batch[kNumBatchOpsMax][2 * kEcc256NumWords];
310 for (
size_t i = 0; i < uj_data_num_traces.num_traces; ++i) {
312 gen_fvsr_data(ecc256_message_batch[i],
false, NULL, kEcc256NumWords);
315 gen_fvsr_data(ecc256_private_key_d0_batch[i],
false, NULL, kEcc256NumWords);
318 gen_mask_data(ecc256_private_key_d1_batch[i], uj_data_masks.en_masks,
322 memcpy(ecc256_private_key_d_batch[i], ecc256_private_key_d0_batch[i],
323 sizeof(ecc256_private_key_d0_batch[i]));
324 memcpy(ecc256_private_key_d_batch[i] + kEcc256NumWords,
325 ecc256_private_key_d1_batch[i],
326 sizeof(ecc256_private_key_d1_batch[i]));
329 gen_fvsr_data(ecc256_secret_key_k0_batch[i],
false, NULL, kEcc256NumWords);
332 gen_mask_data(ecc256_secret_key_k1_batch[i], uj_data_masks.en_masks,
336 memcpy(ecc256_secret_key_k_batch[i], ecc256_secret_key_k0_batch[i],
337 sizeof(ecc256_secret_key_k0_batch[i]));
338 memcpy(ecc256_secret_key_k_batch[i] + kEcc256NumWords,
339 ecc256_secret_key_k1_batch[i],
340 sizeof(ecc256_secret_key_k1_batch[i]));
344 uint32_t ecc256_signature_r[kEcc256NumWords];
345 uint32_t ecc256_signature_s[kEcc256NumWords];
347 for (
size_t i = 0; i < uj_data_num_traces.num_traces; ++i) {
348 otbn_load_app(kOtbnAppP256Ecdsa);
351 p256_ecdsa_sign(ecc256_message_batch[i], ecc256_private_key_d_batch[i],
352 ecc256_signature_r, ecc256_signature_s,
353 ecc256_secret_key_k_batch[i]);
357 penetrationtest_otbn_sca_ecdsa_p256_signature_t uj_output;
358 memcpy(uj_output.r, ecc256_signature_r,
sizeof(ecc256_signature_r));
359 memcpy(uj_output.s, ecc256_signature_s,
sizeof(ecc256_signature_s));
360 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_ecdsa_p256_signature_t, uj,
371 penetrationtest_otbn_sca_num_traces_t uj_data_num_traces;
372 TRY(ujson_deserialize_penetrationtest_otbn_sca_num_traces_t(
373 uj, &uj_data_num_traces));
375 if (uj_data_num_traces.num_traces > kNumBatchOpsMax) {
376 return OUT_OF_RANGE();
380 penetrationtest_otbn_sca_en_masks_t uj_data_masks;
381 TRY(ujson_deserialize_penetrationtest_otbn_sca_en_masks_t(uj,
385 penetrationtest_otbn_sca_ecdsa_p256_sign_t uj_data;
386 TRY(ujson_deserialize_penetrationtest_otbn_sca_ecdsa_p256_sign_t(uj,
389 uint32_t ecc256_message_batch[kNumBatchOpsMax][kEcc256NumWords];
391 uint32_t ecc256_private_key_d0_batch[kNumBatchOpsMax][kEcc256NumWords];
392 uint32_t ecc256_private_key_d1_batch[kNumBatchOpsMax][kEcc256NumWords];
393 uint32_t ecc256_private_key_d_batch[kNumBatchOpsMax][2 * kEcc256NumWords];
395 uint32_t ecc256_secret_key_k0_batch[kNumBatchOpsMax][kEcc256NumWords];
396 uint32_t ecc256_secret_key_k1_batch[kNumBatchOpsMax][kEcc256NumWords];
397 uint32_t ecc256_secret_key_k_batch[kNumBatchOpsMax][2 * kEcc256NumWords];
401 bool run_fixed =
true;
402 for (
size_t i = 0; i < uj_data_num_traces.num_traces; ++i) {
404 gen_fvsr_data(ecc256_message_batch[i], run_fixed, uj_data.msg,
409 gen_fvsr_data(ecc256_private_key_d0_batch[i], run_fixed, uj_data.d0,
414 gen_mask_data(ecc256_private_key_d1_batch[i], uj_data_masks.en_masks,
418 memcpy(ecc256_private_key_d_batch[i], ecc256_private_key_d0_batch[i],
419 sizeof(ecc256_private_key_d0_batch[i]));
420 memcpy(ecc256_private_key_d_batch[i] + kEcc256NumWords,
421 ecc256_private_key_d1_batch[i],
422 sizeof(ecc256_private_key_d1_batch[i]));
427 gen_fvsr_data(ecc256_secret_key_k0_batch[i], run_fixed, uj_data.k0,
431 gen_mask_data(ecc256_secret_key_k1_batch[i], uj_data_masks.en_masks,
435 memcpy(ecc256_secret_key_k_batch[i], ecc256_secret_key_k0_batch[i],
436 sizeof(ecc256_secret_key_k0_batch[i]));
437 memcpy(ecc256_secret_key_k_batch[i] + kEcc256NumWords,
438 ecc256_secret_key_k1_batch[i],
439 sizeof(ecc256_secret_key_k1_batch[i]));
445 uint32_t ecc256_signature_r[kEcc256NumWords];
446 uint32_t ecc256_signature_s[kEcc256NumWords];
448 for (
size_t i = 0; i < uj_data_num_traces.num_traces; ++i) {
449 otbn_load_app(kOtbnAppP256Ecdsa);
452 p256_ecdsa_sign(uj_data.msg, ecc256_private_key_d_batch[i],
453 ecc256_signature_r, ecc256_signature_s,
454 ecc256_secret_key_k_batch[i]);
458 penetrationtest_otbn_sca_ecdsa_p256_signature_t uj_output;
459 memcpy(uj_output.r, ecc256_signature_r,
sizeof(ecc256_signature_r));
460 memcpy(uj_output.s, ecc256_signature_s,
sizeof(ecc256_signature_s));
461 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_ecdsa_p256_signature_t, uj,
471 penetrationtest_cpuctrl_t uj_data;
472 TRY(ujson_deserialize_penetrationtest_cpuctrl_t(uj, &uj_data));
476 TRY(pentest_configure_entropy_source_max_reseed_interval());
478 pentest_init(kPentestTriggerSourceOtbn,
479 kPentestPeripheralEntropy | kPentestPeripheralIoDiv4 |
480 kPentestPeripheralOtbn | kPentestPeripheralCsrng |
481 kPentestPeripheralEdn | kPentestPeripheralHmac |
482 kPentestPeripheralKmac);
488 if (otbn_load_app(kOtbnAppP256KeyFromSeed).value != OTCRYPTO_OK.value) {
493 penetrationtest_device_info_t uj_output;
494 TRY(pentest_configure_cpu(
495 uj_data.icache_disable, uj_data.dummy_instr_disable,
496 uj_data.enable_jittery_clock, uj_data.enable_sram_readback,
497 &uj_output.clock_jitter_locked, &uj_output.clock_jitter_en,
498 &uj_output.sram_main_readback_locked, &uj_output.sram_ret_readback_locked,
499 &uj_output.sram_main_readback_en, &uj_output.sram_ret_readback_en));
502 TRY(pentest_read_device_id(uj_output.device_id));
503 RESP_OK(ujson_serialize_penetrationtest_device_info_t, uj, &uj_output);
510 TRY(keymgr_testutils_startup(&keymgr, &kmac));
512 TRY(keymgr_testutils_advance_state(&keymgr, &kOwnerIntParams));
513 TRY(keymgr_testutils_check_state(&keymgr,
515 LOG_INFO(
"Keymgr entered OwnerIntKey State");
530 penetrationtest_otbn_sca_big_num_t uj_data;
531 TRY(ujson_deserialize_penetrationtest_otbn_sca_big_num_t(uj, &uj_data));
538 static const otbn_app_t kOtbnAppInsnCarryFlag =
540 static const otbn_addr_t kOtbnVarInsnCarryFlagBigNum =
542 static const otbn_addr_t kOtbnVarInsnCarryFlagBigNumOut =
546 otbn_load_app(kOtbnAppInsnCarryFlag);
548 sizeof(uj_data.big_num)));
550 pentest_set_trigger_high();
552 otbn_busy_wait_for_done();
553 pentest_set_trigger_low();
555 penetrationtest_otbn_sca_big_num_t uj_output;
556 memset(uj_output.big_num, 0,
sizeof(uj_output.big_num));
558 uj_output.big_num,
sizeof(uj_output.big_num)));
560 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_big_num_t, uj, &uj_output);
567 penetrationtest_otbn_sca_fixed_seed_t uj_data;
568 TRY(ujson_deserialize_penetrationtest_otbn_sca_fixed_seed_t(uj, &uj_data));
574 bool sample_fixed =
true;
575 for (
size_t it = 0; it < kKeySideloadNumIt; it++) {
576 sideload_params[it].
version = 0x0;
578 memset(sideload_params[it].salt, 0,
sizeof(sideload_params[it].salt));
580 sideload_params[it].
salt[0] = uj_data.fixed_seed;
587 otbn_load_app(kOtbnAppKeySideloadSca);
589 uint32_t key_share_0_l[kKeySideloadNumIt], key_share_0_h[kKeySideloadNumIt];
590 uint32_t key_share_1_l[16], key_share_1_h[kKeySideloadNumIt];
591 uint32_t key_l[kKeySideloadNumIt], key_h[kKeySideloadNumIt];
594 for (
size_t it = 0; it < kKeySideloadNumIt; it++) {
595 TRY(keymgr_testutils_generate_versioned_key(&keymgr, sideload_params[it]));
599 pentest_set_trigger_high();
603 otbn_busy_wait_for_done();
604 pentest_set_trigger_low();
607 otbn_dmem_read(1, kOtbnAppKeySideloadks0l, &key_share_0_l[it]);
608 otbn_dmem_read(1, kOtbnAppKeySideloadks0h, &key_share_0_h[it]);
609 otbn_dmem_read(1, kOtbnAppKeySideloadks1l, &key_share_1_l[it]);
610 otbn_dmem_read(1, kOtbnAppKeySideloadks1h, &key_share_1_h[it]);
611 otbn_dmem_read(1, kOtbnAppKeySideloadkl, &key_l[it]);
612 otbn_dmem_read(1, kOtbnAppKeySideloadkh, &key_h[it]);
616 penetrationtest_otbn_sca_key_t uj_output;
617 for (
size_t it = 0; it < kKeySideloadNumIt; it++) {
618 uj_output.shares[0] = key_share_0_l[it];
619 uj_output.shares[1] = key_share_0_h[it];
620 uj_output.shares[2] = key_share_1_l[it];
621 uj_output.shares[3] = key_share_1_h[it];
622 uj_output.keys[0] = key_l[it];
623 uj_output.keys[1] = key_h[it];
624 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_key_t, uj, &uj_output);
632 penetrationtest_otbn_sca_rsa512_dec_t uj_data;
633 TRY(ujson_deserialize_penetrationtest_otbn_sca_rsa512_dec_t(uj, &uj_data));
635 otbn_load_app(kOtbnAppRsa);
639 uint32_t n_limbs = 2;
645 sizeof(uj_data.mod)));
647 sizeof(uj_data.exp)));
649 sizeof(uj_data.msg)));
651 pentest_set_trigger_high();
655 otbn_busy_wait_for_done();
656 pentest_set_trigger_low();
659 penetrationtest_otbn_sca_rsa512_dec_out_t uj_output;
661 sizeof(uj_output.out)));
662 RESP_OK(ujson_serialize_penetrationtest_otbn_sca_rsa512_dec_out_t, uj,
668 otbn_sca_subcommand_t cmd;
669 TRY(ujson_deserialize_otbn_sca_subcommand_t(uj, &cmd));
671 case kOtbnScaSubcommandEcc256EcdsaKeygenFvsrKeyBatch:
672 return handle_otbn_sca_ecc256_ecdsa_keygen_fvsr_key_batch(uj);
673 case kOtbnScaSubcommandEcc256EcdsaKeygenFvsrSeedBatch:
674 return handle_otbn_sca_ecc256_ecdsa_keygen_fvsr_seed_batch(uj);
675 case kOtbnScaSubcommandEcc256EnMasks:
676 return handle_otbn_sca_ecc256_en_masks(uj);
677 case kOtbnScaSubcommandEcc256SetC:
678 return handle_otbn_sca_ecc256_set_c(uj);
679 case kOtbnScaSubcommandEcc256SetSeed:
680 return handle_otbn_sca_ecc256_set_seed(uj);
681 case kOtbnScaSubcommandEcdsaP256Sign:
682 return handle_otbn_sca_ecdsa_p256_sign(uj);
683 case kOtbnScaSubcommandEcdsaP256SignBatch:
684 return handle_otbn_sca_ecdsa_p256_sign_batch(uj);
685 case kOtbnScaSubcommandEcdsaP256SignFvsrBatch:
686 return handle_otbn_sca_ecdsa_p256_sign_fvsr_batch(uj);
687 case kOtbnScaSubcommandInit:
688 return handle_otbn_pentest_init(uj);
689 case kOtbnScaSubcommandInitKeyMgr:
690 return handle_otbn_pentest_init_keymgr(uj);
691 case kOtbnScaSubcommandInsnCarryFlag:
692 return handle_otbn_sca_insn_carry_flag(uj);
693 case kOtbnScaSubcommandKeySideloadFvsr:
694 return handle_otbn_sca_key_sideload_fvsr(uj);
695 case kOtbnScaSubcommandRsa512Decrypt:
696 return handle_otbn_sca_rsa512_decrypt(uj);
698 LOG_ERROR(
"Unrecognized OTBN SCA subcommand: %d", cmd);
699 return INVALID_ARGUMENT();