Xmega Application Note


AES_driver.h File Reference


Detailed Description

XMEGA AES driver header file.

This file contains the function prototypes and enumerator definitions for various configuration parameters for 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 crypto instruction.

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.

Application note:
AVR1317 Using the XMEGA built in AES accelerator
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Revision
1569
Date
2008-04-22 13:03:43 +0200 (ti, 22 apr 2008)

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.h.

#include "avr_compiler.h"

Include dependency graph for AES_driver.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  AES_interrupt_driver

Defines

#define AES_auto_disable()   ( AES.CTRL = AES.CTRL & (~AES_AUTO_bm) )
 This macro disable the auto start feature in the AES module.
#define AES_auto_enable()   ( AES.CTRL |= AES_AUTO_bm )
 This macro enable the auto start feature in the AES module.
#define AES_BLOCK_LENGTH   16
#define AES_decryption_mode_set()   ( AES.CTRL |= AES_DECRYPT_bm )
 This macro enable AES module decryption mode.
#define AES_encryption_mode_set()   ( AES.CTRL = AES.CTRL & (~AES_DECRYPT_bm) )
 This macro enable AES module encryption mode.
#define AES_error_flag_check()   ((AES.STATUS & AES_ERROR_bm) != 0)
 This macro checks if the error flag is set.
#define AES_software_reset()   ( AES.CTRL = AES_RESET_bm )
 This macro resets all registers in AES module.
#define AES_start()   ( AES.CTRL |= AES_START_bm )
 This macro starts a decryption/encryption.
#define AES_state_ready_flag_check()   ((AES.STATUS & AES_SRIF_bm) != 0)
 This macro checks if AES state ready interrupt flag is set.
#define AES_xor_disable()   ( AES.CTRL = AES.CTRL & (~AES_XOR_bm) )
 This macro disable the xor feature in the AES module.
#define AES_xor_enable()   ( AES.CTRL |= AES_XOR_bm )
 This macro enable the xor feature in the AES module.

Typedefs

typedef struct AES_interrupt_driver AES_interrupt_driver_t

Functions

bool AES_CBC_decrypt (uint8_t *ciphertext, uint8_t *plaintext, uint8_t *keys, 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 *keys, 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_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 *decrypt_key)
 Polled function that generates the last subkey of the Expanded Key needed during decryption.


Define Documentation

 
#define AES_auto_disable (  )     ( AES.CTRL = AES.CTRL & (~AES_AUTO_bm) )

This macro disable the auto start feature in the AES module.

Definition at line 99 of file AES_driver.h.

 
#define AES_auto_enable (  )     ( AES.CTRL |= AES_AUTO_bm )

This macro enable the auto start feature in the AES module.

Definition at line 96 of file AES_driver.h.

#define AES_BLOCK_LENGTH   16

 
#define AES_decryption_mode_set (  )     ( AES.CTRL |= AES_DECRYPT_bm )

This macro enable AES module decryption mode.

Definition at line 93 of file AES_driver.h.

 
#define AES_encryption_mode_set (  )     ( AES.CTRL = AES.CTRL & (~AES_DECRYPT_bm) )

This macro enable AES module encryption mode.

Definition at line 90 of file AES_driver.h.

 
#define AES_error_flag_check (  )     ((AES.STATUS & AES_ERROR_bm) != 0)

This macro checks if the error flag is set.

Return values:
true if AES Error flag is set.
false if AES Error flag not set.

Definition at line 125 of file AES_driver.h.

Referenced by AES_interrupt_driver_start().

 
#define AES_software_reset (  )     ( AES.CTRL = AES_RESET_bm )

This macro resets all registers in AES module.

Definition at line 108 of file AES_driver.h.

Referenced by AES_lastsubkey_generate(), and main().

 
#define AES_start (  )     ( AES.CTRL |= AES_START_bm )

This macro starts a decryption/encryption.

Definition at line 111 of file AES_driver.h.

 
#define AES_state_ready_flag_check (  )     ((AES.STATUS & AES_SRIF_bm) != 0)

This macro checks if AES state ready interrupt flag is set.

Return values:
true if State Ready interrupt flag is set.
false if State Ready interrupt flag is not set.

Definition at line 118 of file AES_driver.h.

 
#define AES_xor_disable (  )     ( AES.CTRL = AES.CTRL & (~AES_XOR_bm) )

This macro disable the xor feature in the AES module.

Definition at line 105 of file AES_driver.h.

 
#define AES_xor_enable (  )     ( AES.CTRL |= AES_XOR_bm )

This macro enable the xor feature in the AES module.

Definition at line 102 of file AES_driver.h.


Typedef Documentation


Function Documentation

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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
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.
Return values:
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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
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.
Return values:
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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
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
Return values:
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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
ciphertext Pointer to the ciphertext that shall be decrypted
plaintext Pointer to where in memory the plaintext (answer) shall be stored.
Return values:
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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
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
Return values:
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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
plaintext Pointer to the plaintext that shall be encrypted
ciphertext Pointer to where in memory the ciphertext (answer) shall be stored.
Return values:
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.

Parameters:
interrupt_driver Pointer to interrupt driver struct.
Return values:
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.

Parameters:
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.

Parameters:
interrupt_driver Pointer to interrupt driver struct.
int_lvl Interrupt level for the AES module.
Return values:
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.

Parameters:
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.

Parameters:
int_lvl The AES interrupt level

Definition at line 655 of file AES_driver.c.

00656 {
00657         AES.INTCTRL = int_lvl;
00658 }

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.

Note:
This code is blocking and will dead lock if no interrupt flags are set.
Parameters:
key Pointer to AES key.
last_sub_key Pointer to where the last subkey of the Expanded Key shall be stored.
Return values:
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 }

@DOC_TITLE@
Generated on Wed Apr 23 08:53:41 2008 for AVR1318 Using the XMEGA built in AES accelerator by doxygen 1.5.5