| 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 only support encryption, since decryption is not required for the transmitter in this application. All transmissions except when sending a Teach Message use the same cryptographic key. This motivates precalculation of the AES key schedule, which speeds up the encryption process considerably. As this application is designed for ATtiny45, there is not enough SRAM to hold the whole key schedule if the larger AES key sizes are used (192 and 256 bits). Parts of the key schedule is therefore stored in on-chip EEPROM memory. Refer to the config.h file for configuration options.

- 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 | calcKeySchedule (const byte __eeprom *key)
void | cipherLookup (byte *block)

## Function Documentation

void calcKeySchedule | ( | const byte __eeprom * | key | ) |

Precalculate AES key schedule from given cipher key.

Definition at line 332 of file aes.c.

References addConstant(), addConstantFromEEPROM(), BLOCK_SIZE, BPOLY, copyBytes(), copyBytesFromEEPROM(), copyBytesToEEPROM(), cycleLeft(), KEY_SIZE, keyScheduleInEEPROM, keyScheduleInSRAM, SCHEDULE_SIZE, SCHEDULE_SPLIT, and subBytes().

Referenced by main(), and transmitTeachMessage().

    00333 {
    00334         byte schedulePos; // Current position inside schedule.
    00335         byte temp[4]; // Temporary word when expanding the key.
    00336         byte roundConstant[4] = { 0x01, 0x00, 0x00, 0x00 };
    00337         byte * keySchedule1 = keyScheduleInSRAM;
    00338 #if SCHEDULE_EXTRA > 0
    00339         byte __eeprom * keySchedule2 = keyScheduleInEEPROM;
    00340 #endif
    00341
    00342         // Copy entire key to start of schedule.
    00343         copyBytesFromEEPROM( keySchedule1, key, KEY_SIZE );
    00344         keySchedule1 += KEY_SIZE;
    00345         // Copy last 4 bytes of key to temp word.
    00346         copyBytes( temp, keySchedule1-4, 4 );
    00347
    00348         // Expand key into schedule buffer 1 first.
    00349         schedulePos = KEY_SIZE;
    00350         while( schedulePos < SCHEDULE_SIZE ) {
    00351                 // Multiple of key size?
    00352                 if( (schedulePos % KEY_SIZE) == 0 ) {
    00353                         cycleLeft( temp ); // Cycle left one byte.
    00354                         subBytes( temp, 4 ); // Substitute each byte.
    00355                         addConstant( temp, roundConstant, 4 ); // Add to temp.
    00356
    00357                         // Modular doubling of round constant's first byte.
    00358                         // This operation is done the following way to ensure cycle count
    00359                         // independent from data contents. Take care when changing this code.
    00360                         xor = 0;
    00361                         if (roundConstant[0] & 0x80) {
    00362                                 xor = BPOLY;
    00363                         }
    00364                         roundConstant[0] <<= 1;
    00365                         roundConstant[0]  ^= xor;
    00366                 }
    00367
    00368 #if KEY_SIZE > 24
    00369                 // Multiple of key size + block size, ie. block size into key.
    00370                 else if( (schedulePos % KEY_SIZE) == BLOCK_SIZE ) {
    00371                         subBytes( temp, 4 ); // Substitute each byte.
    00372                 }
    00373 #endif
    00374
    00375 #if SCHEDULE_EXTRA > 0
    00376                 // Select correct source buffer for addition temp word.
    00377                 if( schedulePos <= SCHEDULE_SPLIT+KEY_SIZE-4 ) {
    00378 #endif
    00379                         // Add with data KEY_SIZE backwards in schedule.
    00380                         addConstant( temp, keySchedule1 - KEY_SIZE, 4 );
    00381
    00382 #if SCHEDULE_EXTRA > 0
    00383                         // Copy temp word to currect destination buffer.
    00384                         if( schedulePos <= SCHEDULE_SPLIT-4 ) {
    00385 #endif
    00386                                 copyBytes( keySchedule1, temp, 4 );
    00387                                 keySchedule1 += 4;
    00388 #if SCHEDULE_EXTRA > 0
    00389                         } else {
    00390                                 copyBytesToEEPROM( keySchedule2, temp, 4 );
    00391                                 keySchedule1 += 4; // We need buffer 1 also.
    00392                                 keySchedule2 += 4;
    00393                         }
    00394                 } else {
    00395                         // Add with data KEY_SIZE backwards in schedule.
    00396                         addConstantFromEEPROM( temp,
    00397                                         keySchedule2 - KEY_SIZE, 4 );
    00398                         copyBytesToEEPROM( keySchedule2, temp, 4 );
    00399                         keySchedule2 += 4;
    00400                 }
    00401 #endif
    00402                 schedulePos += 4;
    00403         }
    00404 }

Here is the call graph for this function:

void cipherLookup | ( | byte * | block | ) |

Use precalculated key schedule to encrypt the given data block.

Definition at line 288 of file aes.c.

References addConstant(), addConstantAndSubstitute(), addConstantFromEEPROM(), addConstantFromEEPROMAndSubstitute(), BLOCK_SIZE, keyScheduleInEEPROM, keyScheduleInSRAM, mixColumns(), ROUNDS, SCHEDULE_SPLIT_BLOCKS, and shiftRows().

Referenced by calcCMAC(), calcCMACSubkey(), and transmitTeachMessage().

    00289 {
    00290         byte * keySchedule1 = keyScheduleInSRAM;
    00291         byte round = 0;
    00292
    00293 #if SCHEDULE_EXTRA > 0
    00294         byte __eeprom * keySchedule2 = keyScheduleInEEPROM;
    00295
    00296         for( ; round < SCHEDULE_SPLIT_BLOCKS; ++round ) {
    00297                 addConstantAndSubstitute( block, keySchedule1, BLOCK_SIZE );
    00298                 shiftRows( block );
    00299                 mixColumns( block );
    00300                 keySchedule1 += BLOCK_SIZE;
    00301         }
    00302
    00303         for( ; round < ROUNDS-1; ++round ) {
    00304                 addConstantFromEEPROMAndSubstitute( block,
    00305                                 keySchedule2, BLOCK_SIZE );
    00306                 shiftRows( block );
    00307                 mixColumns( block );
    00308                 keySchedule2 += BLOCK_SIZE;
    00309         }
    00310
    00311         addConstantFromEEPROMAndSubstitute( block, keySchedule2, BLOCK_SIZE );
    00312         shiftRows( block );
    00313         keySchedule2 += BLOCK_SIZE;
    00314         addConstantFromEEPROM( block, keySchedule2, BLOCK_SIZE );
    00315 #else
    00316         for( ; round < ROUNDS-1; ++round ) {
    00317                 addConstantAndSubstitute( block, keySchedule1, BLOCK_SIZE );
    00318                 shiftRows( block );
    00319                 mixColumns( block );
    00320                 keySchedule1 += BLOCK_SIZE;
    00321         }
    00322
    00323         addConstantAndSubstitute( block, keySchedule1, BLOCK_SIZE );
    00324         shiftRows( block );
    00325         keySchedule1 += BLOCK_SIZE;
    00326         addConstant( block, keySchedule1, BLOCK_SIZE );
    00327 #endif
    00328 }

Here is the call graph for this function:

@DOC_TITLE@