/** * \brief Generate AES sub key * * Get AES sub key by encryption of dummy data. * * \param key Pointer to AES key input. * \param last_sub_key Pointer to AES sub key output. * */ static bool aes_lastsubkey_generate(t_key key, t_key last_sub_key) { bool keygen_ok; aes_software_reset(); /* Set AES encryption of a single block in manual mode. */ aes_configure(AES_ENCRYPT, AES_MANUAL, AES_XOR_OFF); /* Load key into AES key memory. */ aes_set_key(key); /* Load dummy data into AES state memory. It isn't important what is * written, just that a write cycle occurs. */ aes_write_inputdata(dummy_data); /* Start encryption. */ aes_start(); do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); /* If not error. */ if (!aes_is_error()) { /* Store the last subkey. */ aes_get_key(last_sub_key); aes_clear_interrupt_flag(); keygen_ok = true; } else { aes_clear_error_flag(); keygen_ok = false; } return keygen_ok; }
/** * \brief Test AES state interface functions * * This test verifies that the functions used to check the state of the module * are working, and that the clear functions work correctly. * * \param test Current test case */ static void run_aes_state_interface_test(const struct test_case *test) { /* We first reset the module */ aes_software_reset(); /* The module should not be busy or in error */ test_assert_true(test, aes_is_busy(), "Module should not be busy!"); test_assert_true(test, !aes_is_error(), "Module should not be in error!"); /* Get the module into error by trying to start the module before loading * values into state memory */ aes_start(); /* Module should now be in error */ test_assert_true(test, aes_is_error(), "Module should be in error!"); /* Clear the flag and check that it has been cleared */ aes_clear_error_flag(); test_assert_true(test, !aes_is_error(), "Module error flag should have been cleared!"); /* Load up dummy data into the module and do a cycle, then check that * the aes_is_busy() function actually works */ aes_software_reset(); aes_configure(AES_ENCRYPT, AES_MANUAL, AES_XOR_OFF); aes_set_key(encryption_key); aes_write_inputdata(dummy_data); aes_start(); /* Check that the module is busy, the module uses more CPU cycles to * complete than it takes to see if it is busy */ test_assert_true(test, aes_is_busy(), "AES module should be busy!"); do { /* Wait until the module is finished */ } while(aes_is_busy()); /* The module now has data in the status register. We want to clear the * flag without reading the data. First verify that the flag is set */ test_assert_true(test, AES.STATUS & AES_SRIF_bm, "State ready interrupt flag is not set!"); aes_clear_interrupt_flag(); /* Now, check that we have cleared the flag */ test_assert_true(test, !(AES.STATUS & AES_SRIF_bm), "State ready interrupt flag should not be set!"); }
/** * \brief Generate AES sub key * * \note Get AES sub key by encryption of dummy data. * * \param key Pointer to AES key input. * \param last_sub_key Pointer to AES sub key output. * */ static bool aes_lastsubkey_generate(t_key key, t_key last_sub_key) { bool keygen_ok; uint8_t i; /* Before using the AES it is recommended to do an AES software reset to * put the module in known state, in case other parts of your code has * accessed the AES module. */ aes_software_reset(); /* Set AES encryption of a single block in manual mode. */ aes_configure(AES_ENCRYPT, AES_MANUAL, AES_XOR_OFF); /* Load key into AES key memory. */ aes_set_key(key); /* Load dummy data into AES state memory. */ for (i = 0; i < BLOCK_LENGTH; i++) { AES.STATE = 0x00; } /* Start encryption. */ aes_start(); do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); /* If not error. */ if (!aes_is_error()) { /* Store the last subkey. */ aes_get_key(last_sub_key); aes_clear_interrupt_flag(); keygen_ok = true; } else { aes_clear_error_flag(); keygen_ok = false; } return keygen_ok; }