//! \brief Set up and run test suite int main(void) { /* USART init values */ const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS, }; /* Start services */ pmic_init(); sysclk_init(); board_init(); sleepmgr_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); /* Enable the clock for the AES module */ sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); /* Enable global interrupts */ cpu_irq_enable(); // Set callback for AES module aes_set_callback(&int_callback_aes); /* Define test cases */ DEFINE_TEST_CASE(aes_get_set_test, NULL, run_aes_set_and_get_key_test, NULL, "Get and set functions"); DEFINE_TEST_CASE(aes_state_interface_test, NULL, run_aes_state_interface_test, NULL, "Test of AES state functions"); DEFINE_TEST_CASE(aes_encryption_test, NULL, run_aes_encryption_test, NULL, "Encryption with known result"); DEFINE_TEST_CASE(aes_decryption_test, NULL, run_aes_decryption_test, NULL, "Decryption function known result"); DEFINE_TEST_CASE(aes_enc_dec_test, NULL, run_aes_encrypt_and_decrypt_test, NULL, "Encryption and decryption with interrupt and auto mode"); DEFINE_TEST_ARRAY(aes_tests) = { &aes_get_set_test, &aes_state_interface_test, &aes_encryption_test, &aes_decryption_test, &aes_enc_dec_test }; DEFINE_TEST_SUITE(aes_suite, aes_tests, "XMEGA AES driver test suite"); /* Run all test in the suite */ test_suite_run(&aes_suite); while (1) { /* Intentionally left blank */ } }
/** * \brief Run AES driver unit tests. */ int main(void) { const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS }; sysclk_init(); board_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); /* Enable the AES module. */ aes_get_config_defaults(&g_aes_cfg); aes_init(&g_aes_inst, AESA, &g_aes_cfg); aes_enable(&g_aes_inst); /* Enable AES interrupt. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback, 1); /* Define all the test cases. */ DEFINE_TEST_CASE(ecb_mode_test, NULL, run_ecb_mode_test, NULL, "SAM AES ECB mode encryption and decryption test."); DEFINE_TEST_CASE(cbc_mode_test, NULL, run_cbc_mode_test, NULL, "SAM AES CBC mode encryption and decryption test."); DEFINE_TEST_CASE(cfb128_mode_test, NULL, run_cfb128_mode_test, NULL, "SAM AES CFB128 mode encryption and decryption test."); DEFINE_TEST_CASE(ofb_mode_test, NULL, run_ofb_mode_test, NULL, "SAM AES OFB mode encryption and decryption test."); DEFINE_TEST_CASE(ctr_mode_test, NULL, run_ctr_mode_test, NULL, "SAM AES CTR mode encryption and decryption test."); DEFINE_TEST_CASE(ecb_mode_test_pdca, NULL, run_ecb_mode_test_pdca, NULL, "SAM AES ECB mode encryption and decryption with PDCA test."); /* Put test case addresses in an array. */ DEFINE_TEST_ARRAY(aes_tests) = { &ecb_mode_test, &cbc_mode_test, &cfb128_mode_test, &ofb_mode_test, &ctr_mode_test, &ecb_mode_test_pdca, }; /* Define the test suite. */ DEFINE_TEST_SUITE(aes_suite, aes_tests, "SAM AES driver test suite"); /* Run all tests in the test suite. */ test_suite_run(&aes_suite); while (1) { /* Busy-wait forever. */ } }
/** * \brief Test ECB mode encryption and decryption with PDCA. * * \param test Current test case. */ static void run_ecb_mode_test_pdca(const struct test_case *test) { /* Change the AES interrupt callback function. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback_pdca, 1); /* Enable PDCA module clock */ pdca_enable(PDCA); state = false; /* Configure the AES. */ g_aes_inst.aes_cfg->encrypt_mode = AES_ENCRYPTION; g_aes_inst.aes_cfg->key_size = AES_KEY_SIZE_128; g_aes_inst.aes_cfg->dma_mode = AES_DMA_MODE; g_aes_inst.aes_cfg->opmode = AES_ECB_MODE; g_aes_inst.aes_cfg->cfb_size = AES_CFB_SIZE_128; g_aes_inst.aes_cfg->countermeasure_mask = AES_COUNTERMEASURE_TYPE_ALL; aes_set_config(&g_aes_inst); /* Beginning of a new message. */ aes_set_new_message(&g_aes_inst); /* Set the cryptographic key. */ aes_write_key(&g_aes_inst, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be ciphered to the input data registers. */ /* Init PDCA channel with the pdca_options.*/ PDCA_TX_OPTIONS.addr = (void *)ref_plain_text; /* memory address */ PDCA_TX_OPTIONS.pid = AESA_PDCA_ID_TX; /* select peripheral - AESA TX.*/ PDCA_TX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_TX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_TX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_TX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_TX_CHANNEL, &PDCA_TX_OPTIONS); PDCA_RX_OPTIONS.addr = (void *)output_data; /* memory address */ PDCA_RX_OPTIONS.pid = AESA_PDCA_ID_RX; /* select peripheral - AESA RX.*/ PDCA_RX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_RX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_RX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_RX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_RX_CHANNEL, &PDCA_RX_OPTIONS); /* Enable PDCA channel, start transfer data. */ pdca_channel_enable(PDCA_TX_CHANNEL); /* Wait for the end of the encryption process. */ delay_ms(30); /* Disable PDCA channel. */ pdca_channel_disable(PDCA_RX_CHANNEL); pdca_channel_disable(PDCA_TX_CHANNEL); if ((ref_cipher_text_ecb[0] != output_data[0]) || (ref_cipher_text_ecb[1] != output_data[1]) || (ref_cipher_text_ecb[2] != output_data[2]) || (ref_cipher_text_ecb[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode encryption not work!"); state = false; /* Configure the AES. */ g_aes_inst.aes_cfg->encrypt_mode = AES_DECRYPTION; g_aes_inst.aes_cfg->key_size = AES_KEY_SIZE_128; g_aes_inst.aes_cfg->dma_mode = AES_DMA_MODE; g_aes_inst.aes_cfg->opmode = AES_ECB_MODE; g_aes_inst.aes_cfg->cfb_size = AES_CFB_SIZE_128; g_aes_inst.aes_cfg->countermeasure_mask = AES_COUNTERMEASURE_TYPE_ALL; aes_set_config(&g_aes_inst); /* Beginning of a new message. */ aes_set_new_message(&g_aes_inst); /* Set the cryptographic key. */ aes_write_key(&g_aes_inst, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Write the data to be deciphered to the input data registers. */ /* Init PDCA channel with the pdca_options.*/ PDCA_TX_OPTIONS.addr = (void *)ref_cipher_text_ecb; /* memory address */ PDCA_TX_OPTIONS.pid = AESA_PDCA_ID_TX; /* select peripheral - AESA TX.*/ PDCA_TX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_TX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_TX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_TX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_TX_CHANNEL, &PDCA_TX_OPTIONS); PDCA_RX_OPTIONS.addr = (void *)output_data; /* memory address */ PDCA_RX_OPTIONS.pid = AESA_PDCA_ID_RX; /* select peripheral - AESA RX.*/ PDCA_RX_OPTIONS.size = AES_EXAMPLE_REFBUF_SIZE; /* transfer counter */ PDCA_RX_OPTIONS.r_addr = (void *)0; /* next memory address */ PDCA_RX_OPTIONS.r_size = 0; /* next transfer counter */ PDCA_RX_OPTIONS.transfer_size = PDCA_MR_SIZE_WORD; pdca_channel_set_config(PDCA_RX_CHANNEL, &PDCA_RX_OPTIONS); /* Enable PDCA channel, start transfer data. */ pdca_channel_enable(PDCA_TX_CHANNEL); /* Wait for the end of the decryption process. */ delay_ms(30); /* Disable PDCA channel. */ pdca_channel_disable(PDCA_RX_CHANNEL); pdca_channel_disable(PDCA_TX_CHANNEL); /* check the result. */ if ((ref_plain_text[0] != output_data[0]) || (ref_plain_text[1] != output_data[1]) || (ref_plain_text[2] != output_data[2]) || (ref_plain_text[3] != output_data[3])) { flag = false; } else { flag = true; } test_assert_true(test, flag == true, "ECB mode decryption not work!"); /* Disable PDCA module clock */ pdca_disable(PDCA); /* Change back the AES interrupt callback function. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback, 1); }
/** * \brief The main function. */ int main(void) { uint8_t key; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the console */ configure_console(); /* Output example information */ printf("-- AES Example --\r\n"); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Enable the AES module. */ aes_get_config_defaults(&g_aes_cfg); aes_init(&g_aes_inst, AESA, &g_aes_cfg); aes_enable(&g_aes_inst); /* Enable AES interrupt. */ aes_set_callback(&g_aes_inst, AES_INTERRUPT_INPUT_BUFFER_READY, aes_callback, 1); /* Display menu */ display_menu(); while (1) { scanf("%c", (char *)&key); switch (key) { case 'h': display_menu(); break; case '1': printf("ECB mode encryption and decryption test.\r\n"); ecb_mode_test(); break; case '2': printf("CBC mode encryption and decryption test.\r\n"); cbc_mode_test(); break; case '3': printf("CFB128 mode encryption and decryption test.\r\n"); cfb128_mode_test(); break; case '4': printf("OFB mode encryption and decryption test.\r\n"); ofb_mode_test(); break; case '5': printf("CTR mode encryption and decryption test.\r\n"); ctr_mode_test(); break; case 'd': printf("ECB mode encryption and decryption test with PDCA.\r\n"); ecb_mode_test_pdca(); break; default: break; } } }
/** * \brief ECB mode encryption and decryption test with PDC. */ static void ecb_mode_test_pdc(void) { /* Configure PDC. */ g_pdc_tx_packet.ul_addr = (uint32_t)ref_plain_text; g_pdc_tx_packet.ul_size = AES_EXAMPLE_REFBUF_SIZE; g_pdc_rx_packet.ul_addr = (uint32_t)output_data; g_pdc_rx_packet.ul_size = AES_EXAMPLE_REFBUF_SIZE; g_p_aes_pdc = aes_get_pdc_base(AES); /* Configure PDC for data receive & transfer */ pdc_tx_init(g_p_aes_pdc, &g_pdc_tx_packet, NULL); pdc_rx_init(g_p_aes_pdc, &g_pdc_rx_packet, NULL); /* Disable PDC transfers. */ pdc_disable_transfer(g_p_aes_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); printf("\r\n-----------------------------------\r\n"); printf("- 128bit cryptographic key\r\n"); printf("- ECB cipher mode\r\n"); printf("- PDC mode\r\n"); printf("- input of 4 32bit words with PDC\r\n"); printf("-----------------------------------\r\n"); state = false; /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_ENCRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_IDATAR0_START; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* Enable AES interrupt. */ aes_set_callback(AES, AES_INTERRUPT_END_OF_RECEIVE_BUFFER, aes_pdc_callback, 1); /* The initialization vector is not used by the ECB cipher mode. */ /* Enable PDC transfers. */ pdc_enable_transfer(g_p_aes_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); /* Wait for the end of the encryption process. */ while (false == state) { } if ((ref_cipher_text_ecb[0] != output_data[0]) || (ref_cipher_text_ecb[1] != output_data[1]) || (ref_cipher_text_ecb[2] != output_data[2]) || (ref_cipher_text_ecb[3] != output_data[3])) { printf("\r\nKO!!!\r\n"); } else { printf("\r\nOK!!!\r\n"); } printf("\r\n-----------------------------------\r\n"); printf("- 128bit cryptographic key\r\n"); printf("- ECB decipher mode\r\n"); printf("- PDC mode\r\n"); printf("- input of 4 32bit words with PDC\r\n"); printf("-----------------------------------\r\n"); state = false; /* Configure the AES. */ g_aes_cfg.encrypt_mode = AES_DECRYPTION; g_aes_cfg.key_size = AES_KEY_SIZE_128; g_aes_cfg.start_mode = AES_IDATAR0_START; g_aes_cfg.opmode = AES_ECB_MODE; g_aes_cfg.cfb_size = AES_CFB_SIZE_128; g_aes_cfg.lod = false; aes_set_config(AES, &g_aes_cfg); /* Set the cryptographic key. */ aes_write_key(AES, key128); /* The initialization vector is not used by the ECB cipher mode. */ /* Configure PDC for data transfer */ g_pdc_tx_packet.ul_addr = (uint32_t)ref_cipher_text_ecb; /* Configure PDC for data receive & transfer */ pdc_tx_init(g_p_aes_pdc, &g_pdc_tx_packet, NULL); pdc_rx_init(g_p_aes_pdc, &g_pdc_rx_packet, NULL); /* Enable PDC transfers. */ pdc_enable_transfer(g_p_aes_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); /* Wait for the end of the decryption process. */ while (false == state) { } /* check the result. */ if ((ref_plain_text[0] != output_data[0]) || (ref_plain_text[1] != output_data[1]) || (ref_plain_text[2] != output_data[2]) || (ref_plain_text[3] != output_data[3])) { printf("\r\nKO!!!\r\n"); } else { printf("\r\nOK!!!\r\n"); } }
int main( void ) { uint16_t i; /* Enable all three interrupt levels of the PMIC. */ pmic_init(); 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 decryption of a single block with AES interrupt handler. */ //******************************************************** // DECIPHER IN MANUAL MODE: // - 128bit cryptographic key and data // - ECB cipher mode // - XOR disable // - Interrupt call back handler //******************************************************** /* Generate last subkey. */ if (!aes_lastsubkey_generate(key, lastsubkey)) { success = false; } /* Enable global interrupts. */ cpu_irq_enable(); /* Assume no interrupt is finished. */ int_end = false; byte_count = 0; /* Set AES interrupt call back function. */ aes_set_callback(&aes_isr_handler); /* 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_DECRYPT, AES_MANUAL, AES_XOR_OFF); /* Enable the AES low level interrupt. */ aes_isr_configure(AES_INTLVL_LO); /* Load key into AES key memory. */ aes_set_key(lastsubkey); /* Load data into AES state memory. */ aes_write_inputdata(cipher_text); /* Start encryption. */ aes_start(); do{ /* Wait until the AES interrupt is finished. */ } while (!int_end); /* Do AES encryption and decryption of multi blocks. */ //******************************************************** // CIPHER IN AUTO MODE: // - 128bit cryptographic key and data // - CBC cipher mode // - XOR on // - Interrupt call back handler //******************************************************** /* Assume no interrupt is finished. */ int_end = false; byte_count = 0; /* Set AES interrupt call back function. */ aes_set_callback(&aes_isr_cbc_encrypt_handler); /* 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(); /* Load initial vector into AES state memory. */ aes_write_inputdata(init); /* Set AES encryption of a single block in auto mode. */ aes_configure(AES_ENCRYPT, AES_AUTO, AES_XOR_ON); /* Enable the AES low level interrupt. */ aes_isr_configure(AES_INTLVL_LO); /* Load key into AES key memory. */ aes_set_key(key); /* Load data into AES state memory. */ aes_write_inputdata(data_block); // 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 the AES interrupt is finished. */ } while (!int_end); //******************************************************** // DECIPHER IN AUTO MODE: // - 128bit cryptographic key and data // - CBC cipher mode // - XOR off // - Interrupt call back handler //******************************************************** /* Generate last subkey. */ if (!aes_lastsubkey_generate(key, lastsubkey)) { success = false; } /* Assume no interrupt is finished. */ int_end = false; byte_count = 0; /* Set AES interrupt call back function. */ aes_set_callback(&aes_isr_cbc_decrypt_handler); /* 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); /* Enable the AES low level interrupt. */ aes_isr_configure(AES_INTLVL_LO); /* Load key into AES key memory. */ aes_set_key(lastsubkey); /* Load data into AES state memory. */ aes_write_inputdata(cipher_block_ans); // 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 the AES interrupt is finished. */ } while (!int_end); /* Check if decrypted answer is equal to plaintext. */ for (i = 0; i < BLOCK_LENGTH * BLOCK_COUNT ; i++) { if (data_block[i] != plain_block_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(); } }