/** * \brief AES interrupt handler * * \note AES interrupt subroutine in CBC decryption mode. * */ static void aes_isr_cbc_decrypt_handler(void) { /* When CBC is used the answer must be xored with the previous cipher text * or the initialization vector to reconstruct the plaintext. */ /* Set AES decryption of a single block in manual mode. */ aes_configure(AES_DECRYPT, AES_MANUAL, AES_XOR_ON); if(byte_count == 0) { aes_write_inputdata(init); }else { aes_write_inputdata((cipher_block_ans + byte_count - BLOCK_LENGTH)); } aes_read_outputdata((plain_block_ans + byte_count)); byte_count += BLOCK_LENGTH; if(byte_count >= BLOCK_LENGTH * BLOCK_COUNT) { int_end = true; }else { aes_configure(AES_DECRYPT, AES_AUTO, AES_XOR_OFF); /* Load key into AES key memory. */ aes_set_key(lastsubkey); /* Load data into AES state memory. */ aes_write_inputdata((cipher_block_ans + byte_count)); // NOTE: since we're in auto mode, the ciphering process will start as // soon as the correct number of input data is written. In this case, // the process should start when we write the sixteenth byte. } }
/** * \brief Test AES decryption function. * * This test decrypts the pre-encrypted data and checks * whether it is correct. * * \param test Current test case. */ static void run_aes_decryption_test(const struct test_case *test) { t_key decrypted_data; bool success; set_buffer(decrypted_data, 0x00); set_buffer(lastsubkey, 0x00); /* Call helper function to generate a last subkey for decryption */ if (!aes_lastsubkey_generate(encryption_key, lastsubkey)) { success = false; test_assert_true(test, !success, "Could not generate last subkey"); } else { /* Configure module for manual decryption */ aes_software_reset(); aes_set_key(lastsubkey); aes_configure(AES_DECRYPT, AES_MANUAL, AES_XOR_OFF); aes_write_inputdata(pre_encrypted_data); aes_start(); do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); aes_read_outputdata(decrypted_data); /* Verify that the decrypted data is correct */ success = compare_data_block(decrypted_data, encryption_data); test_assert_true(test, success, "Decrypted values do not match excepted values"); } }
/** * \brief AES interrupt handler * * \note AES interrupt subroutine in CBC encryption mode. * */ static void aes_isr_cbc_encrypt_handler(void) { aes_read_outputdata((cipher_block_ans + byte_count)); byte_count += BLOCK_LENGTH; if(byte_count >= BLOCK_LENGTH * BLOCK_COUNT) { int_end = true; }else { /* Load key into AES key memory. */ aes_set_key(key); /* Load data into AES state memory. */ aes_write_inputdata((data_block + byte_count)); // NOTE: since we're in auto mode, the ciphering process will start as // soon as the correct number of input data is written. In this case, // the process should start when we write the sixteenth byte. } }
/** * \brief AES interrupt handler * * \note AES interrupt subroutine in Electronic Code Book (ECB) mode. * */ static void aes_isr_handler(void) { uint8_t i; /* Store the result if not error. */ if (!aes_is_error()) { aes_read_outputdata(single_ans); } else { success = false; } /* Check if encrypted answer is equal to cipher result. */ for (i = 0; i < BLOCK_LENGTH ; i++ ) { if (plain_text[i] != single_ans[i]) { success = false; } } /* AES interrupt ends. */ int_end = true; }
/** * \brief Test AES encryption function * * This test generates an encrypted byte string from a key and input, * and compares it to a pre-encrypted value. * * \param test Current test case. */ static void run_aes_encryption_test(const struct test_case *test) { t_data encrypted_data; bool success; /* Zero out the output data storage */ set_buffer(encrypted_data, 0x00); /* Reset the module */ aes_software_reset(); /* * Configure AES module to encrypt, triggered by software, * with no XOR */ aes_configure(AES_ENCRYPT, AES_MANUAL, AES_XOR_OFF); aes_set_key(encryption_key); aes_write_inputdata(encryption_data); aes_start(); do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); aes_read_outputdata(encrypted_data); /* Verify that this data is correct by comparing it * to our pre-encrypted value */ success = compare_data_block(encrypted_data, pre_encrypted_data); test_assert_true(test, success, "Encrypted values do not match pre-encrypted" " values"); }
int main( void ) { uint8_t i; board_init(); sysclk_init(); sleepmgr_init(); /* Assume that everything is ok */ success = true; /* Enable the AES clock. */ sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); /* Do AES encryption and decryption of a single block. */ //******************************************************** // CIPHER IN MANUAL MODE: // - 128bit cryptographic key and data // - ECB cipher mode // - XOR disable // - Polling AES State Ready Interrupt flag //******************************************************** /* 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); /* Disable the AES interrupt. */ aes_isr_configure(AES_INTLVL_OFF); /* Load key into AES key memory. */ aes_set_key(key); /* Load data into AES state memory. */ aes_write_inputdata(plain_text); /* Start encryption. */ aes_start(); do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); /* Store the result if not error. */ if (!aes_is_error()) { aes_read_outputdata(single_ans); } else { success = false; } /* Check if encrypted answer is equal to cipher result. */ for (i = 0; i < BLOCK_LENGTH ; i++ ) { if (cipher_text[i] != single_ans[i]) { success = false; } } //******************************************************** // DECIPHER IN AUTO MODE: // - 128bit cryptographic key and data // - ECB cipher mode // - XOR disable // - Polling AES State Ready Interrupt flag //******************************************************** /* Generate last subkey. */ if (!aes_lastsubkey_generate(key, lastsubkey)) { success = false; } /* 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 decryption of a single block in auto mode. */ aes_configure(AES_DECRYPT, AES_AUTO, AES_XOR_OFF); /* Disable the AES interrupt. */ aes_isr_configure(AES_INTLVL_OFF); /* Load key into AES key memory. */ aes_set_key(lastsubkey); /* Load data into AES state memory. */ aes_write_inputdata(cipher_text); // NOTE: since we're in auto mode, the ciphering process will start as soon // as the correct number of input data is written. In this case, the // process should start when we write the sixteenth byte. do { /* Wait until AES is finished or an error occurs. */ } while (aes_is_busy()); /* Store the result if not error. */ if (!aes_is_error()) { aes_read_outputdata(single_ans); } else { success = false; } /* Check if decrypted answer is equal to plaintext. */ for (i = 0; i < BLOCK_LENGTH ; i++ ) { if (plain_text[i] != single_ans[i]) { success = false; } } /* Disable the AES clock. */ sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); /* Indicate final result by lighting LED. */ if (success) { /* If the example ends up here every thing is ok. */ ioport_set_pin_low(LED0_GPIO); } else { /* If the example ends up here something is wrong. */ ioport_set_pin_low(LED1_GPIO); } while (true) { /* Go to sleep. */ sleepmgr_enter_sleep(); } }
/** * \brief Callback for AES interrupt */ static void int_callback_aes(void) { aes_read_outputdata(output_data); aes_is_finished = true; }