Xmega Application Note | |||||
This file contains the function implementations the XMEGA AES driver.
The driver is not intended for size and/or speed critical code, since most functions are just a few lines of code, and the function call overhead would decrease code performance. The driver is intended for rapid prototyping and documentation purposes for getting started with the XMEGA AES module.
For size and/or speed critical code, it is recommended to copy the function contents directly into your application instead of making a function call.
Several functions use the following construct: "some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ..." Although the use of the ternary operator ( if ? then : else ) is discouraged, in some occasions the operator makes it possible to write pretty clean and neat code. In this driver, the construct is used to set or not set a configuration bit based on a boolean input parameter, such as the "some_parameter" in the example above.
Copyright (c) 2008, Atmel Corporation All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Definition in file AES_driver.c.
#include "AES_driver.h"
Go to the source code of this file.
Functions | |
bool | AES_CBC_decrypt (uint8_t *ciphertext, uint8_t *plaintext, uint8_t *key, uint8_t *init, uint16_t block_count) |
Polled function that does AES CBC decryption on a given number of 128-bit data block. | |
bool | AES_CBC_encrypt (uint8_t *plaintext, uint8_t *ciphertext, uint8_t *key, uint8_t *init, uint16_t block_count) |
Polled function that does AES CBC encryption on a given number of 128-bit data block. | |
bool | AES_decrypt (uint8_t *ciphertext, uint8_t *plaintext, uint8_t *key) |
Polled function that does an AES decryption on one 128-bit data block. | |
bool | AES_decrypt_backtoback (uint8_t *ciphertext, uint8_t *plaintext) |
Polled function that does an AES decryption on one 128-bit data block. | |
bool | AES_encrypt (uint8_t *plaintext, uint8_t *ciphertext, uint8_t *key) |
Polled function that does an AES encryption on one 128-bit data block. | |
bool | AES_encrypt_backtoback (uint8_t *plaintext, uint8_t *ciphertext) |
Polled function that does an AES encryption on one 128-bit data block. | |
bool | AES_interrupt_driver_finished (AES_interrupt_driver_t *interrupt_driver) |
Function that check if the interrupt driver is finished. | |
void | AES_interrupt_driver_init (AES_interrupt_driver_t *interrupt_driver, uint8_t *input_ptr, uint8_t *output_ptr, uint8_t *AES_key, uint8_t *AES_CBC_init, uint8_t block_count, bool decrypt) |
Function that initialize the interrupt driver. | |
bool | AES_interrupt_driver_start (AES_interrupt_driver_t *interrupt_driver, AES_INTLVL_t int_lvl) |
Function that starts the AES interrupt driver. | |
void | AES_interrupt_handler (AES_interrupt_driver_t *interrupt_driver) |
Function that control the AES when State Ready Interrupts occurs. | |
void | AES_interruptlevel_set (AES_INTLVL_t int_lvl) |
Function that sets AES interrupt level. | |
bool | AES_lastsubkey_generate (uint8_t *key, uint8_t *last_sub_key) |
Polled function that generates the last subkey of the Expanded Key needed during decryption. |
bool AES_CBC_decrypt | ( | uint8_t * | ciphertext, | |
uint8_t * | plaintext, | |||
uint8_t * | key, | |||
uint8_t * | init, | |||
uint16_t | block_count | |||
) |
Polled function that does AES CBC decryption on a given number of 128-bit data block.
ciphertext | Pointer to the ciphertext that shall be decrypted. | |
plaintext | Pointer to where the plaintext (answer) shall be stored. | |
key | Pointer to the last subkey of the Expanded Key. | |
init | Pointer to the initialization vector used in the CBC. | |
block_count | The number of blocks to decrypt. |
true | If the AES CBC decryption was successful. | |
false | If the AES CBC decryption was not successful. |
Definition at line 580 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00582 { 00583 bool CBC_ok = true; 00584 00585 /* Temporary values used to reduce memory access. */ 00586 uint8_t * temp_plaintext = plaintext; 00587 uint8_t * temp_ciphertext = ciphertext; 00588 00589 for(uint8_t blocks_left = block_count; blocks_left > 0; blocks_left--){ 00590 00591 /* Load key into AES key memory. */ 00592 uint8_t * temp_key = key; 00593 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00594 AES.KEY = *(temp_key++); 00595 } 00596 00597 /* Load ciphertext into AES state memory. */ 00598 uint8_t * temp = temp_ciphertext; 00599 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00600 AES.STATE = *(temp++); 00601 } 00602 00603 temp_ciphertext = temp; 00604 00605 /* Set AES in decryption mode and enable xor feature and start the AES. */ 00606 AES.CTRL |= (AES_DECRYPT_bm | AES_XOR_bm | AES_START_bm); 00607 00608 do{ 00609 /* Wait until AES is finished or an error occurs. */ 00610 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00611 00612 /* If not error. */ 00613 if((AES.STATUS & AES_ERROR_bm) == 0){ 00614 00615 /* The first block is xored with the initialization vector. */ 00616 if(blocks_left == block_count){ 00617 /* Load into AES state memory. */ 00618 uint8_t * temp_init = init; 00619 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00620 AES.STATE = *(temp_init++); 00621 } 00622 } 00623 /* The other blocks is xored with the previous ciphertext block. */ 00624 else{ 00625 /* Load into AES state memory. */ 00626 uint8_t * last_ciphertext = temp_ciphertext - (AES_BLOCK_LENGTH*2); 00627 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00628 AES.STATE = *(last_ciphertext++); 00629 } 00630 } 00631 00632 /* Disable XOR feature before next round. */ 00633 AES.CTRL = AES.CTRL & (~AES_XOR_bm); 00634 00635 /* Store the result. */ 00636 uint8_t * temp = temp_plaintext; 00637 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00638 *(temp++) = AES.STATE; 00639 } 00640 temp_plaintext = temp; 00641 }else{ 00642 CBC_ok = false; 00643 } 00644 00645 } 00646 return CBC_ok; 00647 }
bool AES_CBC_encrypt | ( | uint8_t * | plaintext, | |
uint8_t * | ciphertext, | |||
uint8_t * | key, | |||
uint8_t * | init, | |||
uint16_t | block_count | |||
) |
Polled function that does AES CBC encryption on a given number of 128-bit data block.
plaintext | Pointer to the plaintext that shall be encrypted. | |
ciphertext | Pointer to where in memory the ciphertext (answer) shall be stored. | |
key | Pointer to the key. | |
init | Pointer to the initialization vector used in the CBC. | |
block_count | The number of blocks to encrypt. |
true,: | The AES CBC encryption was successful. | |
false,: | The AES CBC encryption was not successful. |
Definition at line 507 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00509 { 00510 bool CBC_ok = true; 00511 00512 /* The first encryption uses the initialization vector. */ 00513 uint8_t * temp_init = init; 00514 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00515 AES.STATE = *(temp_init++); 00516 } 00517 00518 /* Set AES in encryption mode and enables the XOR feature and the AUTO start 00519 * mode. */ 00520 AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm))| AES_XOR_bm |AES_AUTO_bm; 00521 00522 /* Temporary values used to reduce memory access. */ 00523 uint8_t * temp_plaintext = plaintext; 00524 uint8_t * temp_ciphertext = ciphertext; 00525 00526 for(uint8_t blocks_left = block_count; blocks_left > 0; blocks_left--){ 00527 00528 /* Load key into AES key memory. */ 00529 uint8_t * temp_key = key; 00530 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00531 AES.KEY = *(temp_key++); 00532 } 00533 00534 /* Load plaintext into AES state memory. Auto starts. */ 00535 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00536 AES.STATE = *(temp_plaintext++); 00537 } 00538 00539 00540 do{ 00541 /* Wait until AES is finished or an error occurs. */ 00542 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00543 00544 /* If not error. */ 00545 if((AES.STATUS & AES_ERROR_bm) == 0){ 00546 00547 /* Store result. */ 00548 uint8_t * temp = temp_ciphertext; 00549 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00550 *(temp++) = AES.STATE; 00551 } 00552 temp_ciphertext = temp; 00553 }else{ 00554 CBC_ok = false; 00555 } 00556 } 00557 00558 /* Turn off auto mode and xor feature. */ 00559 AES.CTRL = (AES.CTRL & ~( AES_XOR_bm |AES_AUTO_bm)); 00560 00561 return CBC_ok; 00562 }
bool AES_decrypt | ( | uint8_t * | ciphertext, | |
uint8_t * | plaintext, | |||
uint8_t * | key | |||
) |
Polled function that does an AES decryption on one 128-bit data block.
ciphertext | Pointer to the ciphertext that shall be decrypted | |
plaintext | Pointer to where in memory the plaintext (answer) shall be stored. | |
key | Pointer to the DES key |
true | If the AES decryption was successful. | |
false | If the AES decryption was not successful. |
Definition at line 396 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00398 { 00399 bool decrypt_ok; 00400 00401 /* Load key into AES key memory. */ 00402 uint8_t * temp_key = key; 00403 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00404 AES.KEY = *(temp_key++); 00405 } 00406 00407 /* Load data into AES state memory. */ 00408 uint8_t * temp_ciphertext = ciphertext; 00409 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00410 AES.STATE = *(temp_ciphertext++); 00411 } 00412 00413 /* Set AES in decryption mode and start the AES.*/ 00414 AES.CTRL |= (AES_START_bm | AES_DECRYPT_bm); 00415 00416 do{ 00417 /* Wait until AES is finished or an error occurs. */ 00418 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00419 00420 /* If not error. */ 00421 if((AES.STATUS & AES_ERROR_bm) == 0){ 00422 /* Store the result. */ 00423 uint8_t * temp_plaintext = plaintext; 00424 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00425 *(temp_plaintext++) = AES.STATE; 00426 } 00427 decrypt_ok = true; 00428 }else{ 00429 decrypt_ok = false; 00430 00431 } 00432 return decrypt_ok; 00433 }
bool AES_decrypt_backtoback | ( | uint8_t * | ciphertext, | |
uint8_t * | plaintext | |||
) |
Polled function that does an AES decryption on one 128-bit data block.
Function equal to the AES_decrypt function but the key is not loaded into the key memory. The function require that the key already is in the key memory. Used when encryption and decryption with the same key is done every other time.
ciphertext | Pointer to the ciphertext that shall be decrypted | |
plaintext | Pointer to where in memory the plaintext (answer) shall be stored. |
true | If the AES decryption was successful. | |
false | If the AES decryption was not successful. |
Definition at line 728 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00729 { 00730 bool decrypt_ok; 00731 00732 /* Load data into AES state memory. */ 00733 uint8_t * temp_ciphertext = ciphertext; 00734 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00735 AES.STATE = *(temp_ciphertext++); 00736 } 00737 00738 /* Set AES in decryption mode and start the AES.*/ 00739 AES.CTRL |= (AES_START_bm | AES_DECRYPT_bm); 00740 00741 00742 do{ 00743 /* Wait until AES is finished or an error occurs. */ 00744 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00745 00746 /* If not error. */ 00747 if((AES.STATUS & AES_ERROR_bm) == 0){ 00748 /* Store the result. */ 00749 uint8_t * temp_plaintext = plaintext; 00750 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00751 *(temp_plaintext++) = AES.STATE; 00752 } 00753 decrypt_ok = true; 00754 }else{ 00755 decrypt_ok = false; 00756 00757 } 00758 return decrypt_ok; 00759 }
bool AES_encrypt | ( | uint8_t * | plaintext, | |
uint8_t * | ciphertext, | |||
uint8_t * | key | |||
) |
Polled function that does an AES encryption on one 128-bit data block.
plaintext | Pointer to the plaintext that shall be encrypted | |
ciphertext | Pointer to where in memory the ciphertext (answer) shall be stored. | |
key | Pointer to the AES key |
true | If the AES encryption was successful. | |
false | If the AES encryption was not successful. |
Definition at line 345 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00346 { 00347 bool encrypt_ok; 00348 00349 /* Load key into AES key memory. */ 00350 uint8_t * temp_key = key; 00351 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00352 AES.KEY = *(temp_key++); 00353 } 00354 00355 /* Load data into AES state memory. */ 00356 uint8_t * temp_plaintext = plaintext; 00357 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00358 AES.STATE = *(temp_plaintext++); 00359 } 00360 00361 /* Set AES in encryption mode and start AES. */ 00362 AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm; 00363 00364 do{ 00365 /* Wait until AES is finished or an error occurs. */ 00366 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00367 00368 /* If not error. */ 00369 if((AES.STATUS & AES_ERROR_bm) == 0){ 00370 /* Store the result. */ 00371 uint8_t * temp_ciphertext = ciphertext; 00372 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00373 *(temp_ciphertext++) = AES.STATE; 00374 } 00375 encrypt_ok = true; 00376 }else{ 00377 encrypt_ok = false; 00378 00379 } 00380 return encrypt_ok; 00381 }
bool AES_encrypt_backtoback | ( | uint8_t * | plaintext, | |
uint8_t * | ciphertext | |||
) |
Polled function that does an AES encryption on one 128-bit data block.
Function equal to the AES_encrypt function but the key is not loaded into the key memory. The function require that the key already is in the key memory. Used when encryption and decryption with the same key is done every other time.
plaintext | Pointer to the plaintext that shall be encrypted | |
ciphertext | Pointer to where in memory the ciphertext (answer) shall be stored. |
true | If the AES encryption was successful. | |
false | If the AES encryption was not successful. |
Definition at line 678 of file AES_driver.c.
References AES_BLOCK_LENGTH.
Referenced by main().
00679 { 00680 bool encrypt_ok; 00681 00682 /* Load data into AES state memory. */ 00683 uint8_t * temp_plaintext = plaintext; 00684 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00685 AES.STATE = *(temp_plaintext++); 00686 } 00687 00688 /* Set AES in encryption mode and start AES. */ 00689 AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm; 00690 00691 00692 do{ 00693 /* Wait until AES is finished or an error occurs. */ 00694 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00695 00696 /* If not error. */ 00697 if((AES.STATUS & AES_ERROR_bm) == 0){ 00698 /* Store the result. */ 00699 uint8_t * temp_ciphertext = ciphertext; 00700 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00701 *(temp_ciphertext++) = AES.STATE; 00702 } 00703 encrypt_ok = true; 00704 }else{ 00705 encrypt_ok = false; 00706 00707 } 00708 return encrypt_ok; 00709 }
bool AES_interrupt_driver_finished | ( | AES_interrupt_driver_t * | interrupt_driver | ) |
Function that check if the interrupt driver is finished.
interrupt_driver | Pointer to interrupt driver struct. |
true | The AES interrupt driver is finished. | |
false | The AES interrupt driver is not finished. |
Definition at line 326 of file AES_driver.c.
References AES_interrupt_driver::blocks_left.
Referenced by main().
00327 { 00328 bool finished = (interrupt_driver->blocks_left == 0); 00329 return finished; 00330 }
void AES_interrupt_driver_init | ( | AES_interrupt_driver_t * | interrupt_driver, | |
uint8_t * | input_ptr, | |||
uint8_t * | output_ptr, | |||
uint8_t * | AES_key, | |||
uint8_t * | AES_CBC_init, | |||
uint8_t | block_count, | |||
bool | decrypt | |||
) |
Function that initialize the interrupt driver.
interrupt_driver | Pointer to interrupt driver struct . | |
input_ptr | Pointer to the input blocks (plaintext/ciphertext). | |
output_ptr | Pointer to where to store the output. | |
AES_key | Pointer to the key used by the AES algorithm. | |
AES_CBC_init | Pointer to initialization vector needed in CBC. | |
block_count | The number of block that is being encrypted/decrypted. | |
decrypt | Bool that determine if encryption or decryption is done. |
Definition at line 81 of file AES_driver.c.
References AES_interrupt_driver::block_count, AES_interrupt_driver::blocks_left, AES_interrupt_driver::decrypt, AES_interrupt_driver::init_ptr, AES_interrupt_driver::input_ptr, AES_interrupt_driver::key_ptr, and AES_interrupt_driver::output_ptr.
Referenced by main().
00088 { 00089 /* Initialize interrupt driver struct. */ 00090 interrupt_driver->block_count = block_count; 00091 interrupt_driver->blocks_left = block_count; 00092 interrupt_driver->output_ptr = output_ptr; 00093 interrupt_driver->input_ptr = input_ptr; 00094 interrupt_driver->key_ptr = AES_key; 00095 interrupt_driver->init_ptr = AES_CBC_init; 00096 interrupt_driver->decrypt = decrypt; 00097 }
bool AES_interrupt_driver_start | ( | AES_interrupt_driver_t * | interrupt_driver, | |
AES_INTLVL_t | int_lvl | |||
) |
Function that starts the AES interrupt driver.
CBC is used if the number of blocks is more than one.
interrupt_driver | Pointer to interrupt driver struct. | |
int_lvl | Interrupt level for the AES module. |
true | Starting the AES interrupt driver was successful. | |
false | Starting the AES interrupt driver was not successful. |
Definition at line 112 of file AES_driver.c.
References AES_BLOCK_LENGTH, AES_error_flag_check, AES_interrupt_driver::block_count, AES_interrupt_driver::decrypt, AES_interrupt_driver::init_ptr, AES_interrupt_driver::input_ptr, and AES_interrupt_driver::key_ptr.
Referenced by main().
00114 { 00115 bool start_ok; 00116 00117 /* Remove pending AES interrupts. */ 00118 AES.STATUS = (AES_ERROR_bm | AES_SRIF_bm); 00119 00120 /* Set AES to the desired interrupt level. 00121 * NOTE: If interrupt level is set to off, interrupts will never execute. */ 00122 AES.INTCTRL = int_lvl; 00123 00124 /* Put AES module in right mode. */ 00125 if(interrupt_driver->decrypt){ 00126 AES.CTRL |= AES_DECRYPT_bm; 00127 }else{ 00128 AES.CTRL = AES.CTRL & (~AES_DECRYPT_bm); 00129 } 00130 00131 /* If encryption and there are more than one block CBC is used. In CBC 00132 * encryption the first plaintext block is xored with the initialization 00133 * vector. */ 00134 if((interrupt_driver->block_count > 1) && !(interrupt_driver->decrypt)){ 00135 00136 /* Load key to AES Key memory. */ 00137 uint8_t * temp_key_ptr = interrupt_driver->key_ptr; 00138 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00139 AES.KEY = *(temp_key_ptr++); 00140 } 00141 00142 /* Load the first plaintext block to AES State memory. */ 00143 uint8_t * temp_input_ptr = interrupt_driver->input_ptr; 00144 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00145 AES.STATE = *(temp_input_ptr++); 00146 } 00147 interrupt_driver->input_ptr = temp_input_ptr; 00148 00149 /* Enable Auto mode and the XOR feature. */ 00150 AES.CTRL = AES.CTRL | AES_XOR_bm | AES_AUTO_bm; 00151 00152 /* Load the initialization vector to the AES State memory. 00153 * The initialization vector is xored with the plaintext block already 00154 * loaded into the memory and the AES module is auto started. */ 00155 uint8_t * temp_init_ptr = interrupt_driver->init_ptr; 00156 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00157 AES.STATE = *(temp_init_ptr++); 00158 } 00159 00160 /* Check if error flag is set. */ 00161 start_ok = !(AES_error_flag_check()); 00162 } 00163 /* If decryption or encryption of a single block the xor feature is not 00164 * used. */ 00165 else{ 00166 00167 /* Load key to AES Key memory. */ 00168 volatile uint8_t * temp_key_ptr = interrupt_driver->key_ptr; 00169 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00170 AES.KEY = *(temp_key_ptr++); 00171 } 00172 00173 /* Enable Auto mode. */ 00174 AES.CTRL |= AES_AUTO_bm; 00175 00176 /* Load the first input block to AES State memory. */ 00177 uint8_t * temp_input_ptr = interrupt_driver->input_ptr; 00178 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00179 AES.STATE = *(temp_input_ptr++); 00180 } 00181 00182 /* Update input pointer. */ 00183 interrupt_driver->input_ptr = temp_input_ptr; 00184 00185 /* Check if error flag is set. */ 00186 start_ok = !(AES_error_flag_check()); 00187 } 00188 00189 return start_ok; 00190 }
void AES_interrupt_handler | ( | AES_interrupt_driver_t * | interrupt_driver | ) |
Function that control the AES when State Ready Interrupts occurs.
CBC is used if the number of blocks is more than one.
interrupt_driver | Pointer to interrupt driver struct. |
Definition at line 200 of file AES_driver.c.
References AES_BLOCK_LENGTH, AES_interrupt_driver::block_count, AES_interrupt_driver::blocks_left, AES_interrupt_driver::decrypt, AES_interrupt_driver::init_ptr, AES_interrupt_driver::input_ptr, AES_interrupt_driver::key_ptr, and AES_interrupt_driver::output_ptr.
Referenced by ISR().
00201 { 00202 /* If encryption is done, the answer can be read out directly from the 00203 * state memory. Then the output pointer is updated. */ 00204 if(!(interrupt_driver->decrypt)){ 00205 00206 /* Store result to memory. */ 00207 uint8_t * temp_output_ptr = interrupt_driver->output_ptr; 00208 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00209 *(temp_output_ptr++) = AES.STATE; 00210 } 00211 00212 /* Update output pointer and the number of blocks left to 00213 * encrypt/decrypt. */ 00214 interrupt_driver->output_ptr = temp_output_ptr; 00215 interrupt_driver->blocks_left -= 1; 00216 00217 /* If there are more blocks to encrypt a new encryption is started. */ 00218 if(interrupt_driver->blocks_left > 0){ 00219 00220 /* Load key to AES Key memory. */ 00221 uint8_t * temp_key_ptr = interrupt_driver->key_ptr; 00222 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00223 AES.KEY = *(temp_key_ptr++); 00224 } 00225 00226 /* Load the next plaintext to the AES State memory. The block is xored 00227 * with the previous encrypted block and the AES module is auto 00228 * started. */ 00229 uint8_t * temp_input_ptr = interrupt_driver->input_ptr; 00230 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00231 AES.STATE = *(temp_input_ptr++); 00232 } 00233 00234 /* Update input pointer. */ 00235 interrupt_driver->input_ptr = temp_input_ptr; 00236 } 00237 } 00238 /* When decryption is done, the answer can only be read out directly if 00239 * there only is one block to decrypt. If there are more than one block and 00240 * CBC is used the answer must be xored with the previous cipher text or 00241 * the initialization vector to reconstruct the plaintext. */ 00242 else{ 00243 00244 /* If only one block should be decrypted the plaintext can be read out 00245 * directly from the AES State memory. */ 00246 if(interrupt_driver->block_count == 1){ 00247 00248 /* Store result to memory. */ 00249 uint8_t * temp_output_pointer = interrupt_driver->output_ptr; 00250 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00251 *(temp_output_pointer + i) = AES.STATE; 00252 } 00253 } 00254 /* If there are more than one block to decrypt. */ 00255 else{ 00256 00257 /* Disable of Auto mode and enable on the xor feature. */ 00258 AES.CTRL = (AES.CTRL & (~AES_AUTO_bm)) | AES_XOR_bm; 00259 00260 /* If it is the first block that is decrypted the answer must be 00261 * xored with initialization vector to reconstruct the first 00262 * plaintext. */ 00263 uint8_t * temp_ptr; 00264 uint8_t temp_blocks_left = interrupt_driver->blocks_left; 00265 if(interrupt_driver->block_count == temp_blocks_left){ 00266 temp_ptr = interrupt_driver->init_ptr; 00267 } 00268 /* Else the answer must be xored with previous ciphertext value to 00269 * reconstruct the plaintext. */ 00270 else{ 00271 temp_ptr = interrupt_driver->input_ptr -(AES_BLOCK_LENGTH*2); 00272 } 00273 00274 /* Xor the initialization vector or the previous ciphertext with 00275 * the answer from the decryption. */ 00276 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00277 AES.STATE = *(temp_ptr++); 00278 } 00279 00280 /* Store the result. */ 00281 uint8_t * temp_output_ptr = interrupt_driver->output_ptr; 00282 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00283 *(temp_output_ptr++) = AES.STATE; 00284 } 00285 00286 /* Update output pointer and the number of blocks left to 00287 * encrypt/decrypt. */ 00288 interrupt_driver->output_ptr = temp_output_ptr; 00289 interrupt_driver->blocks_left -= 1; 00290 00291 /* If there are more block to decrypt a new decryption is started. */ 00292 if(interrupt_driver->blocks_left > 0){ 00293 00294 /* Enable the Auto mode and disable the xor feature. */ 00295 AES.CTRL = (AES.CTRL & (~AES_XOR_bm)) | AES_AUTO_bm; 00296 00297 /* Load key to AES Key memory. */ 00298 uint8_t * temp_key_ptr = interrupt_driver->key_ptr; 00299 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00300 AES.KEY = *(temp_key_ptr++); 00301 } 00302 00303 /* Load the next ciphertext block to the AES State memory. The 00304 * AES module is auto started. */ 00305 uint8_t * temp_input_ptr = interrupt_driver->input_ptr; 00306 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00307 AES.STATE = *(temp_input_ptr++); 00308 } 00309 00310 /* Update the input pointer. */ 00311 interrupt_driver->input_ptr = temp_input_ptr; 00312 } 00313 } 00314 } 00315 }
void AES_interruptlevel_set | ( | AES_INTLVL_t | int_lvl | ) |
Function that sets AES interrupt level.
int_lvl | The AES interrupt level |
Definition at line 655 of file AES_driver.c.
bool AES_lastsubkey_generate | ( | uint8_t * | key, | |
uint8_t * | last_sub_key | |||
) |
Polled function that generates the last subkey of the Expanded Key needed during decryption.
key | Pointer to AES key. | |
last_sub_key | Pointer to where the last subkey of the Expanded Key shall be stored. |
true | If generating the last subkey was successful. | |
false | If generating the last subkey was not successful. |
Definition at line 450 of file AES_driver.c.
References AES_BLOCK_LENGTH, and AES_software_reset.
Referenced by main().
00451 { 00452 bool keygen_ok; 00453 AES_software_reset(); 00454 00455 /* Load key into AES key memory. */ 00456 uint8_t * temp_key = key; 00457 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00458 AES.KEY = *(temp_key++); 00459 } 00460 00461 /* Load dummy data into AES state memory. */ 00462 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00463 AES.STATE = 0x00; 00464 } 00465 00466 /* Set AES in encryption mode and start AES. */ 00467 AES.CTRL = (AES.CTRL & (~AES_DECRYPT_bm)) | AES_START_bm; 00468 00469 00470 do{ 00471 /* Wait until AES is finished or an error occurs. */ 00472 }while((AES.STATUS & (AES_SRIF_bm|AES_ERROR_bm) ) == 0); 00473 00474 /* If not error. */ 00475 if((AES.STATUS & AES_ERROR_bm) == 0){ 00476 /* Store the last subkey. */ 00477 uint8_t * temp_last_sub_key = last_sub_key; 00478 for(uint8_t i = 0; i < AES_BLOCK_LENGTH; i++){ 00479 *(temp_last_sub_key++) = AES.KEY; 00480 } 00481 AES.STATUS = AES_SRIF_bm; 00482 keygen_ok = true; 00483 }else{ 00484 AES.STATUS = AES_ERROR_bm; 00485 keygen_ok = false; 00486 00487 } 00488 return keygen_ok; 00489 }
Generated on Wed Apr 23 08:53:41 2008 for AVR1318 Using the XMEGA built in AES accelerator by ![]() |