Skip to content

Commit

Permalink
[pentest] Load fixed seed after each dif_aes_start
Browse files Browse the repository at this point in the history
With the recent changes in the PRNG, it is necessary to reseed the
internal AES state after the AUX register has been set by using the
dif_aes_start() function. We need to do this when we want to switch
off masking for AES SCA tests.

Signed-off-by: Pascal Nasahl <[email protected]>
  • Loading branch information
nasahlpa committed Jan 20, 2025
1 parent e91a4d2 commit 8a379c6
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 12 deletions.
47 changes: 42 additions & 5 deletions sw/device/sca/aes_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,37 @@ dif_aes_transaction_t transaction = {
.ctrl_aux_lock = false,
};

/**
* Poll the IDLE AES register.
*
*/
static void aes_sca_wait_for_idle(void) {
bool idle = false;
do {
SS_CHECK_DIF_OK(dif_aes_get_status(&aes, kDifAesStatusIdle, &idle));
} while (!idle);
}

/**
* Load fixed seed into AES.
*
* Before calling this function, use
* aes_testutils_masking_prng_zero_output_seed() to initialize the entropy
* complex for performing AES SCA measurements with masking switched off. This
* function then loads the fixed seed into the AES, allowing the disable the
* masking.
*
* @param key Key.
* @param key_len Key length.
*/
static void aes_sca_load_fixed_seed(void) {
aes_sca_wait_for_idle();
// Load magic seed such that masking is turned off. We need to do this after
// dif_aes_start() as then the force_masks is correctly set.
SS_CHECK_DIF_OK(dif_aes_trigger(&aes, kDifAesTriggerPrngReseed));
aes_sca_wait_for_idle();
}

/**
* Mask and configure key.
*
Expand Down Expand Up @@ -192,7 +223,17 @@ static void aes_key_mask_and_config(const uint8_t *key, size_t key_len) {
key_shares.share0[i] =
pentest_non_linear_layer(pentest_next_lfsr(1, kPentestLfsrMasking));
}
#if !OT_IS_ENGLISH_BREAKFAST
CHECK_STATUS_OK(aes_testutils_masking_prng_zero_output_seed());
#endif
SS_CHECK_DIF_OK(dif_aes_start(&aes, &transaction, &key_shares, NULL));

#if !OT_IS_ENGLISH_BREAKFAST
if (transaction.force_masks) {
// Disable masking. Force the masking PRNG output value to 0.
aes_sca_load_fixed_seed();
}
#endif
}

/**
Expand Down Expand Up @@ -768,11 +809,7 @@ bool test_main(void) {
if (transaction.force_masks) {
LOG_INFO("Initializing entropy complex.");
CHECK_STATUS_OK(aes_testutils_masking_prng_zero_output_seed());
CHECK_DIF_OK(dif_aes_trigger(&aes, kDifAesTriggerPrngReseed));
bool idle = false;
do {
CHECK_DIF_OK(dif_aes_get_status(&aes, kDifAesStatusIdle, &idle));
} while (!idle);
aes_sca_load_fixed_seed();
}
#endif
CHECK_DIF_OK(dif_aes_trigger(&aes, kDifAesTriggerDataOutClear));
Expand Down
40 changes: 33 additions & 7 deletions sw/device/tests/penetrationtests/firmware/sca/aes_sca.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum {
kAesKeyLengthMax = 32,
kAesKeyLength = 16,
kAesTextLength = 16,
kTestTimeout = (1000 * 1000),
/**
* Number of cycles (at `kClockFreqCpuHz`) that Ibex should sleep to minimize
* noise during AES operations. Caution: This number should be chosen to
Expand Down Expand Up @@ -147,6 +148,28 @@ dif_aes_transaction_t transaction = {
.ctrl_aux_lock = false,
};

/**
* Load fixed seed into AES.
*
* Before calling this function, use
* aes_testutils_masking_prng_zero_output_seed() to initialize the entropy
* complex for performing AES SCA measurements with masking switched off. This
* function then loads the fixed seed into the AES, allowing the disable the
* masking.
*
* @param key Key.
* @param key_len Key length.
*/
static status_t aes_sca_load_fixed_seed(void) {
AES_TESTUTILS_WAIT_FOR_STATUS(&aes, kDifAesStatusIdle, true, kTestTimeout);
// Load magic seed such that masking is turned off. We need to do this after
// dif_aes_start() as then the force_masks is correctly set.
TRY(dif_aes_trigger(&aes, kDifAesTriggerPrngReseed));
AES_TESTUTILS_WAIT_FOR_STATUS(&aes, kDifAesStatusIdle, true, kTestTimeout);

return OK_STATUS();
}

/**
* Mask and configure key.
*
Expand Down Expand Up @@ -178,6 +201,13 @@ static status_t aes_key_mask_and_config(const uint8_t *key, size_t key_len) {
}
TRY(dif_aes_start(&aes, &transaction, &key_shares, NULL));

#if !OT_IS_ENGLISH_BREAKFAST
if (transaction.force_masks) {
// Disable masking. Force the masking PRNG output value to 0.
TRY(aes_sca_load_fixed_seed());
}
#endif

return OK_STATUS();
}

Expand Down Expand Up @@ -640,16 +670,12 @@ status_t handle_aes_pentest_seed_lfsr(ujson_t *uj) {
}
// Load the magic seed into the PRNG. After this, the PRNG outputs
// an all-zero vector.
TRY(dif_aes_trigger(&aes, kDifAesTriggerPrngReseed));
bool idle = false;
do {
TRY(dif_aes_get_status(&aes, kDifAesStatusIdle, &idle));
} while (!idle);
// Load the PRNG output into the buffer stage.
TRY(dif_aes_trigger(&aes, kDifAesTriggerDataOutClear));
TRY(aes_sca_load_fixed_seed());
}
#endif

TRY(dif_aes_trigger(&aes, kDifAesTriggerDataOutClear));
AES_TESTUTILS_WAIT_FOR_STATUS(&aes, kDifAesStatusIdle, true, kTestTimeout);
return OK_STATUS();
}

Expand Down

0 comments on commit 8a379c6

Please sign in to comment.