5 #include "sw/device/sca/otbn_vertical/ecc256_keygen_serial.h"
11 #include "sw/device/lib/testing/entropy_testutils.h"
13 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
16 #include "sw/device/tests/penetrationtests/firmware/lib/pentest_lib.h"
19 #include "otbn_regs.h"
25 kEcc256SeedNumBytes = 320 / 8,
29 kEcc256SeedNumWords = kEcc256SeedNumBytes /
sizeof(uint32_t),
33 kEcc256CoordNumBytes = 256 / 8,
37 kEcc256CoordNumWords = kEcc256CoordNumBytes /
sizeof(uint32_t),
41 kEcc256ModePrivateKeyOnly = 1,
45 kEcc256ModeKeypair = 2,
49 kNumBatchOpsMax = 256,
56 kIbexOtbnSleepCycles = 800,
65 static const otbn_addr_t kOtbnVarMode =
67 static const otbn_addr_t kOtbnVarSeed0 =
69 static const otbn_addr_t kOtbnVarSeed1 =
71 static const otbn_addr_t kOtbnVarD0 =
73 static const otbn_addr_t kOtbnVarD1 =
75 static const otbn_addr_t kOtbnVarX =
77 static const otbn_addr_t kOtbnVarY =
83 uint32_t batch_share0[kNumBatchOpsMax][kEcc256SeedNumWords];
88 uint32_t batch_share1[kNumBatchOpsMax][kEcc256SeedNumWords];
94 uint32_t d0_batch[kEcc256SeedNumWords];
95 uint32_t d1_batch[kEcc256SeedNumWords];
103 static bool run_fixed =
true;
110 static bool en_masks =
false;
121 uint32_t ecc256_seed[kEcc256SeedNumWords] = {
122 0x016064e9, 0x11e3f4d6, 0xac3a6fa7, 0xaba11a1b, 0x8f9271d1,
123 0x22b79d5f, 0x1176f31d, 0xb5ac3a51, 0x99a082d7, 0x484eb366,
126 uint32_t ecc256_C[kEcc256SeedNumWords] = {
127 0x016064e9, 0x11e3f4d6, 0xac3a6fa7, 0xaba11a1b, 0x8f9271d1,
128 0x22b79d5f, 0x1176f31d, 0xb5ac3a51, 0x99a082d7, 0x484eb366,
131 uint32_t random_number[kEcc256CoordNumWords] = {
132 0x016064e9, 0x11e3f4d6, 0xac3a6fa7, 0xaba11a1b,
133 0x22b79d5f, 0x1176f31d, 0xb5ac3a51, 0x99a082d7,
136 uint32_t ecc256_fixed_number[kEcc256CoordNumWords] = {
137 0x04030201, 0x00000000, 0x00000000, 0x00000000,
138 0x00000000, 0x00000000, 0x00000000, 0x00000000,
141 void ecc256_en_masks(
const uint8_t *enable,
size_t enable_len) {
158 void ecc256_set_seed(
const uint8_t *seed,
size_t seed_len) {
159 SS_CHECK(seed_len == kEcc256SeedNumBytes);
160 memcpy(ecc256_seed, seed, seed_len);
163 uint32_t temp[kEcc256SeedNumWords];
175 void ecc256_set_c(
const uint8_t *C,
size_t len) {
176 SS_CHECK(len == kEcc256SeedNumBytes);
194 static void p256_run_keygen(uint32_t mode,
const uint32_t *share0,
195 const uint32_t *share1) {
201 otbn_dmem_write(kEcc256SeedNumWords, share0, kOtbnVarSeed0));
203 otbn_dmem_write(kEcc256SeedNumWords, share1, kOtbnVarSeed1));
206 pentest_set_trigger_high();
207 pentest_call_and_sleep(otbn_manual_trigger, kIbexOtbnSleepCycles,
false,
210 pentest_set_trigger_low();
213 void ecc256_ecdsa_keygen_fvsr_seed_batch(
const uint8_t *data,
size_t data_len) {
214 uint32_t num_traces = 0;
215 uint32_t batch_digest[kEcc256SeedNumWords];
216 uint8_t dummy[kEcc256SeedNumBytes];
217 SS_CHECK(data_len ==
sizeof(num_traces));
220 if (num_traces > kNumBatchOpsMax) {
221 LOG_ERROR(
"Too many traces for one batch.");
226 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
230 for (uint32_t i = 0; i < num_traces; ++i) {
232 memcpy(batch_share0[i], ecc256_seed, kEcc256SeedNumBytes);
234 prng_rand_bytes((
unsigned char *)batch_share0[i], kEcc256SeedNumBytes);
237 prng_rand_bytes((
unsigned char *)batch_share1[i], kEcc256SeedNumBytes);
239 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
240 batch_share1[i][j] = 0;
243 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
244 batch_share0[i][j] ^= batch_share1[i][j];
248 run_fixed = dummy[0] & 0x1;
251 for (uint32_t i = 0; i < num_traces; ++i) {
252 p256_run_keygen(kEcc256ModePrivateKeyOnly, batch_share0[i],
257 otbn_dmem_read(kEcc256SeedNumWords, kOtbnVarD0, d0_batch));
259 otbn_dmem_read(kEcc256SeedNumWords, kOtbnVarD1, d1_batch));
264 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
265 batch_digest[j] ^= d0_batch[j];
271 kEcc256SeedNumWords * 4);
287 static void add_arrays(uint8_t *dest, uint8_t *source,
size_t dest_len,
291 for (
size_t i = 0; i < source_len; i++) {
292 temp += (uint16_t)source[i] + dest[i];
293 dest[i] = (uint8_t)(temp & 0x00FF);
297 for (
size_t i = source_len; i < dest_len; i++) {
298 temp += (uint16_t)dest[i];
299 dest[i] = (uint8_t)(temp & 0x00FF);
304 void ecc256_ecdsa_keygen_fvsr_key_batch(
const uint8_t *data,
size_t data_len) {
305 uint32_t num_traces = 0;
306 uint32_t batch_digest[kEcc256SeedNumWords];
307 uint8_t dummy[kEcc256SeedNumBytes];
308 SS_CHECK(data_len ==
sizeof(num_traces));
311 if (num_traces > kNumBatchOpsMax) {
312 LOG_ERROR(
"Too many traces for one batch.");
317 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
321 for (uint32_t i = 0; i < num_traces; ++i) {
323 memcpy(batch_share0[i], ecc256_seed, kEcc256SeedNumBytes);
327 memcpy(batch_share0[i], ecc256_C, kEcc256SeedNumBytes);
329 add_arrays((
unsigned char *)batch_share0[i],
330 (
unsigned char *)random_number, kEcc256SeedNumBytes,
331 kEcc256CoordNumBytes);
334 prng_rand_bytes((
unsigned char *)batch_share1[i], kEcc256SeedNumBytes);
336 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
337 batch_share1[i][j] = 0;
340 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
341 batch_share0[i][j] ^= batch_share1[i][j];
346 run_fixed = dummy[0] & 0x1;
349 for (uint32_t i = 0; i < num_traces; ++i) {
350 p256_run_keygen(kEcc256ModePrivateKeyOnly, batch_share0[i],
355 otbn_dmem_read(kEcc256SeedNumWords, kOtbnVarD0, d0_batch));
357 otbn_dmem_read(kEcc256SeedNumWords, kOtbnVarD1, d1_batch));
362 for (uint32_t j = 0; j < kEcc256SeedNumWords; ++j) {
363 batch_digest[j] ^= d0_batch[j];
368 kEcc256SeedNumWords * 4);
383 static void p256_ecdsa_gen_secret_key(
const uint32_t *seed,
384 const uint32_t *mask, uint32_t *d0,
387 uint32_t share0[kEcc256SeedNumWords];
388 for (
size_t i = 0; i < kEcc256SeedNumWords; i++) {
389 share0[i] = seed[i] ^ mask[i];
393 p256_run_keygen(kEcc256ModePrivateKeyOnly, share0, mask);
414 static void p256_ecdsa_gen_keypair(
const uint32_t *seed,
const uint32_t *mask,
415 uint32_t *d0, uint32_t *d1, uint32_t *x,
418 uint32_t share0[kEcc256SeedNumWords];
419 for (
size_t i = 0; i < kEcc256SeedNumWords; i++) {
420 share0[i] = seed[i] ^ mask[i];
424 p256_run_keygen(kEcc256ModeKeypair, share0, mask);
433 void ecc256_ecdsa_secret_keygen(
const uint8_t *mask,
size_t mask_len) {
434 if (mask_len != kEcc256SeedNumBytes) {
435 LOG_ERROR(
"Invalid mask length %hu", (uint8_t)mask_len);
440 uint32_t ecc256_mask[kEcc256SeedNumWords];
441 memcpy(ecc256_mask, mask, kEcc256SeedNumBytes);
443 uint32_t ecc256_d0[kEcc256SeedNumWords];
444 uint32_t ecc256_d1[kEcc256SeedNumWords];
445 p256_ecdsa_gen_secret_key(ecc256_seed, ecc256_mask, ecc256_d0, ecc256_d1);
448 kEcc256SeedNumBytes);
450 kEcc256SeedNumBytes);
453 void ecc256_ecdsa_gen_keypair(
const uint8_t *mask,
size_t mask_len) {
454 if (mask_len != kEcc256SeedNumBytes) {
455 LOG_ERROR(
"Invalid mask length %hu", (uint8_t)mask_len);
460 uint32_t ecc256_mask[kEcc256SeedNumWords];
461 memcpy(ecc256_mask, mask, kEcc256SeedNumBytes);
463 uint32_t ecc256_d0[kEcc256SeedNumWords];
464 uint32_t ecc256_d1[kEcc256SeedNumWords];
465 uint32_t ecc256_x[kEcc256CoordNumWords];
466 uint32_t ecc256_y[kEcc256CoordNumWords];
467 p256_ecdsa_gen_keypair(ecc256_seed, ecc256_mask, ecc256_d0, ecc256_d1,
471 kEcc256SeedNumBytes);
473 kEcc256SeedNumBytes);
475 kEcc256CoordNumBytes);
477 kEcc256CoordNumBytes);