| Remote Access Control |

# aes.h File Reference

## Detailed Description

Header file for AES public functions.

This file contains the function prototypes for the AES algorithm. The implementation is found in the aes.c file. It supports encryption and decryption using on-the-fly calculation of the key schedule. Precalculation of key schedules for all associated transmitters' secret keys would use too much memory. Encryption is used for generating the CMAC while decryption is used when in learn mode and a transmitter's secret key is encrypted using the system's shared key. Note that the last round key of the key schedule must be prepared using prepareInvCipher() before decrypting using the invCipher() function. Encryption using the cipher() funciton is straight-forward and only needs an SRAM workspace and the encryption key.

- File: aes.h
- Compiler: IAR EWAVR 4.11B
- Supported devices: ATtiny45/85
- AppNote: AVR411 - Secure Rolling Code Algorithm for Wireless Link

Author:
  Atmel Corporation: http://www.atmel.com
  Support email: avr@atmel.com

Name

Revision
  1193

Date
  2006-10-31 14:21:08 +0100 (ti, 31 okt 2006)

Copyright (c) 2006, 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.h.

`#include "common.h"`
`#include "config.h"`

Include dependency graph for aes.h:

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

Go to the source code of this file.

## Functions
void | cipher (byte *block, byte *scheduleBuffer, const byte *key)
void | invCipher (byte *block, byte *scheduleBuffer)
void | prepareInvCipher (byte *scheduleBuffer, const byte *key)

## Function Documentation

void cipher | ( | byte * | block,
|  | byte * | scheduleBuffer,
|  | const byte * | key |
| ) |  |  |

Encrypt data block with on-the-fly calculation of key schedule in 'scheduleBuffer'.

Definition at line 833 of file aes.c.

References addConstant(), addConstantAndSubstitute(), BLOCK_SIZE, copyBytes(), KEY_SIZE, keyExpansion(), mixColumns(), ROUNDS, and shiftRows().

Referenced by calcCMAC(), and calcCMACSubkey().

    00834 {
    00835         byte roundConstant[4] = { 0x01, 0x00, 0x00, 0x00 };
    00836
    00837         copyBytes( scheduleBuffer, key, KEY_SIZE );
    00838 #if SCHEDULE_KEY_REPETITIONS > 1
    00839         initialKeyExpansion( scheduleBuffer, roundConstant );
    00840 #endif
    00841
    00842 #if KEY_SIZE == 16
    00843         byte round;
    00844         for( round = 0; round < ROUNDS-1; ++round ) {
    00845                 addConstantAndSubstitute( block, scheduleBuffer, BLOCK_SIZE );
    00846                 shiftRows( block );
    00847                 mixColumns( block );
    00848
    00849                 keyExpansion( scheduleBuffer, roundConstant );
    00850         }
    00851
    00852         addConstantAndSubstitute( block, scheduleBuffer, BLOCK_SIZE );
    00853         shiftRows( block );
    00854
    00855         keyExpansion( scheduleBuffer, roundConstant );
    00856         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00857
    00858 #elif KEY_SIZE == 24
    00859         byte round;
    00860         for( round = 0; round < ROUNDS-3; round += 3 ) {
    00861                 addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00862                 shiftRows( block );
    00863                 mixColumns( block );
    00864
    00865                 addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00866                 shiftRows( block );
    00867                 mixColumns( block );
    00868
    00869                 addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*2, BLOCK_SIZE );
    00870                 shiftRows( block );
    00871                 mixColumns( block );
    00872
    00873                 keyExpansion( scheduleBuffer, roundConstant );
    00874         }
    00875
    00876         addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00877         shiftRows( block );
    00878         mixColumns( block );
    00879
    00880         addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00881         shiftRows( block );
    00882         mixColumns( block );
    00883
    00884         addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*2, BLOCK_SIZE );
    00885         shiftRows( block );
    00886
    00887         keyExpansion( scheduleBuffer, roundConstant );
    00888         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00889
    00890 #elif KEY_SIZE == 32
    00891         byte round;
    00892         for( round = 0; round < ROUNDS-2; round += 2 ) {
    00893                 addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00894                 shiftRows( block );
    00895                 mixColumns( block );
    00896
    00897                 addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00898                 shiftRows( block );
    00899                 mixColumns( block );
    00900
    00901                 keyExpansion( scheduleBuffer, roundConstant );
    00902         }
    00903
    00904         addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00905         shiftRows( block );
    00906         mixColumns( block );
    00907
    00908         addConstantAndSubstitute( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00909         shiftRows( block );
    00910
    00911         keyExpansion( scheduleBuffer, roundConstant );
    00912         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00913
    00914 #else
    00915   #error Unsupported key size.
    00916 #endif
    00917 }

Here is the call graph for this function:

void invCipher | ( | byte * | block,
|  | byte * | scheduleBuffer |
| ) |  |  |

Decrypt data block using prepared key schedule state from 'scheduleBuffer'.

Definition at line 929 of file aes.c.

References addConstant(), BLOCK_SIZE, BPOLY, invKeyExpansion(), invMixColumns(), invShiftRows(), invSubstituteAndAddConstant(), LAST_ROUND_CONSTANT, and ROUNDS.

Referenced by learnMode().

    00930 {
    00931         byte roundConstant[4] = { LAST_ROUND_CONSTANT, 0x00, 0x00, 0x00 };
    00932
    00933 #if KEY_SIZE == 16
    00934         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00935
    00936         byte round;
    00937         for( round = 0; round < ROUNDS-1; ++round ) {
    00938                 invKeyExpansion( scheduleBuffer, roundConstant );
    00939
    00940                 invShiftRows( block );
    00941                 invSubstituteAndAddConstant( block, scheduleBuffer, BLOCK_SIZE );
    00942                 invMixColumns( block );
    00943         }
    00944
    00945         invKeyExpansion( scheduleBuffer, roundConstant );
    00946
    00947         invShiftRows( block );
    00948         invSubstituteAndAddConstant( block, scheduleBuffer, BLOCK_SIZE );
    00949
    00950 #elif KEY_SIZE == 24
    00951         // Backtrace last update of round constant, since it is never
    00952         // used, due to the use of two KEY_SIZEs in schedule buffer.
    00953         if( (roundConstant[0] ^ BPOLY) == 0 ) {
    00954                 roundConstant[0] = 0x80;
    00955         } else {
    00956                 roundConstant[0] >>= 1;
    00957         }
    00958
    00959         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00960
    00961         byte round;
    00962         for( round = 0; round < ROUNDS-3; round += 3 ) {
    00963                 invKeyExpansion( scheduleBuffer, roundConstant );
    00964
    00965                 invShiftRows( block );
    00966                 invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*2, BLOCK_SIZE );
    00967                 invMixColumns( block );
    00968
    00969                 invShiftRows( block );
    00970                 invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00971                 invMixColumns( block );
    00972
    00973                 invShiftRows( block );
    00974                 invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00975                 invMixColumns( block );
    00976         }
    00977
    00978         invKeyExpansion( scheduleBuffer, roundConstant );
    00979
    00980         invShiftRows( block );
    00981         invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*2, BLOCK_SIZE );
    00982         invMixColumns( block );
    00983
    00984         invShiftRows( block );
    00985         invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*1, BLOCK_SIZE );
    00986         invMixColumns( block );
    00987
    00988         invShiftRows( block );
    00989         invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE*0, BLOCK_SIZE );
    00990
    00991 #elif KEY_SIZE == 32
    00992         addConstant( block, scheduleBuffer, BLOCK_SIZE );
    00993
    00994         byte round;
    00995         for( round = 0; round < ROUNDS-2; round += 2 ) {
    00996                 invKeyExpansion( scheduleBuffer, roundConstant );
    00997
    00998                 invShiftRows( block );
    00999                 invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE, BLOCK_SIZE );
    01000                 invMixColumns( block );
    01001
    01002                 invShiftRows( block );
    01003                 invSubstituteAndAddConstant( block, scheduleBuffer, BLOCK_SIZE );
    01004                 invMixColumns( block );
    01005         }
    01006
    01007         invKeyExpansion( scheduleBuffer, roundConstant );
    01008
    01009         invShiftRows( block );
    01010         invSubstituteAndAddConstant( block, scheduleBuffer + BLOCK_SIZE, BLOCK_SIZE );
    01011         invMixColumns( block );
    01012
    01013         invShiftRows( block );
    01014         invSubstituteAndAddConstant( block, scheduleBuffer, BLOCK_SIZE );
    01015
    01016 #else
    01017   #error Unsupported key size.
    01018 #endif
    01019 }

Here is the call graph for this function:

void prepareInvCipher | ( | byte * | scheduleBuffer,
|  | const byte * | key |
| ) |  |  |

Calculate starting point for key schedule to be used for decryption.

Definition at line 921 of file aes.c.

References calcLastRoundKey(), copyBytes(), and KEY_SIZE.

Referenced by learnMode().

    00922 {
    00923         copyBytes( scheduleBuffer, key, KEY_SIZE );
    00924         calcLastRoundKey( scheduleBuffer );
    00925 }

Here is the call graph for this function:

@DOC_TITLE@