Remote Access Control


aes.c File Reference


Detailed Description

Source file for AES public and support functions.

This file contains the function implementation for the AES algorithm. Refer to the aes.h file for more details.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Name
Revision
4331
Date
2008-08-07 16:44:55 +0200 (to, 07 aug 2008)

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

#include "aes.h"
#include "common.h"
#include "config.h"

Include dependency graph for aes.c:

Go to the source code of this file.

Defines

#define BPOLY   0x1b

Functions

static void addConstant (byte *bytes, const byte *constant, byte count)
static void addConstantAndSubstitute (byte *bytes, const byte *constant, byte count)
static void addConstantFromEEPROMAndSubstitute (byte *bytes, const byte __eeprom *constant, byte count)
void calcKeySchedule (const byte __eeprom *key)
void cipherLookup (byte *block)
static void cycleLeft (byte *row)
static void mixColumn (byte *column)
static void mixColumns (byte *state)
static void shiftRows (byte *state)
static void subBytes (byte *bytes, byte count)

Variables

__no_init byte __eeprom keyScheduleInEEPROM [SCHEDULE_EXTRA]
static byte keyScheduleInSRAM [SCHEDULE_SPLIT]
static const byte __flash sBox [256]


Define Documentation

#define BPOLY   0x1b

Lower 8 bits of AES polynomial (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1).

Definition at line 55 of file aes.c.

Referenced by calcKeySchedule(), and mixColumn().


Function Documentation

static void addConstant ( byte bytes,
const byte constant,
byte  count 
) [static]

XOR 'count' bytes from 'constant' buffer into 'bytes' buffer in SRAM.

Definition at line 233 of file aes.c.

Referenced by calcKeySchedule(), and cipherLookup().

00234 {
00235         // Copy to temporary variables for optimization.
00236         byte * tempDestination = bytes;
00237         const byte * tempSource = constant;
00238         byte tempCount = count;
00239         byte tempValue;
00240 
00241         do {
00242                  // Add in GF(2), ie. XOR.
00243                 tempValue = *tempDestination ^ *tempSource++;
00244                 *tempDestination++ = tempValue;
00245         } while( --tempCount );
00246 }

static void addConstantAndSubstitute ( byte bytes,
const byte constant,
byte  count 
) [static]

XOR 'count' bytes from 'constant' buffer into 'bytes' and substitute using S-Box.

Definition at line 251 of file aes.c.

References sBox.

Referenced by cipherLookup().

00252 {
00253         // Copy to temporary variables for optimization.
00254         byte * tempDestination = bytes;
00255         const byte * tempSource = constant;
00256         byte tempCount = count;
00257         byte tempValue;
00258 
00259         do {
00260                 // Add in GF(2), ie. XOR.
00261                 tempValue = *tempDestination ^ *tempSource++;
00262                 *tempDestination++ = sBox[ tempValue ];
00263         } while( --tempCount );
00264 }

static void addConstantFromEEPROMAndSubstitute ( byte bytes,
const byte __eeprom *  constant,
byte  count 
) [static]

XOR 'count' bytes from 'constant' buffer in EEPROM into 'bytes' and substitute using S-Box.

Definition at line 269 of file aes.c.

References sBox.

Referenced by cipherLookup().

00271 {
00272         // Copy to temporary variables for optimization.
00273         byte * tempDestination = bytes;
00274         byte tempCount = count;
00275         byte tempValue;
00276         EEAR = (unsigned short int) constant;
00277 
00278         do {
00279                 EECR |= (1<<EERE);
00280                 ++EEAR;
00281                 tempValue = *tempDestination ^ EEDR; // Add in GF(2), ie. XOR.
00282                 *tempDestination++ = sBox[ tempValue ];
00283         } while( --tempCount );
00284 }

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:

static void cycleLeft ( byte row  )  [static]

Cycle a 4-byte array left once.

Definition at line 103 of file aes.c.

Referenced by calcKeySchedule().

00104 {
00105         byte temp = row[0];
00106         row[0] = row[1];
00107         row[1] = row[2];
00108         row[2] = row[3];
00109         row[3] = temp;
00110 }

static void mixColumn ( byte column  )  [static]

Perform an AES column mix operation on the 4 bytes in 'column' buffer.

Definition at line 115 of file aes.c.

References BPOLY.

Referenced by mixColumns().

00116 {
00117         byte result0, result1, result2, result3;
00118         byte column0, column1, column2, column3;
00119         byte xor;
00120 
00121         // This generates more effective code, at least
00122         // with the IAR C compiler.
00123         column0 = column[0];
00124         column1 = column[1];
00125         column2 = column[2];
00126         column3 = column[3];
00127 
00128         // Partial sums (modular addition using XOR).
00129         result0 = column1 ^ column2 ^ column3;
00130         result1 = column0 ^ column2 ^ column3;
00131         result2 = column0 ^ column1 ^ column3;
00132         result3 = column0 ^ column1 ^ column2;
00133 
00134         // Multiply column bytes by 2 modulo BPOLY.
00135         // This operation is done the following way to ensure cycle count
00136         // independent from data contents. Take care when changing this code.
00137         xor = 0;
00138         if (column0 & 0x80) {
00139                 xor = BPOLY;
00140         }
00141         column0 <<= 1;
00142         column0  ^= xor;
00143         
00144         xor = 0;
00145         if (column1 & 0x80) {
00146                 xor = BPOLY;
00147         }
00148         column1 <<= 1;
00149         column1  ^= xor;
00150         
00151         xor = 0;
00152         if (column2 & 0x80) {
00153                 xor = BPOLY;
00154         }
00155         column2 <<= 1;
00156         column2  ^= xor;
00157         
00158         xor = 0;
00159         if (column3 & 0x80) {
00160                 xor = BPOLY;
00161         }
00162         column3 <<= 1;
00163         column3  ^= xor;
00164 
00165         // Final sums stored into original column bytes.
00166         column[0] = result0 ^ column0 ^ column1;
00167         column[1] = result1 ^ column1 ^ column2;
00168         column[2] = result2 ^ column2 ^ column3;
00169         column[3] = result3 ^ column0 ^ column3;
00170 }

static void mixColumns ( byte state  )  [static]

Perform AES column mixing for the whole AES block/state.

Definition at line 175 of file aes.c.

References mixColumn().

Referenced by cipherLookup().

00176 {
00177         mixColumn( state + 0*4 );
00178         mixColumn( state + 1*4 );
00179         mixColumn( state + 2*4 );
00180         mixColumn( state + 3*4 );
00181 }

Here is the call graph for this function:

static void shiftRows ( byte state  )  [static]

Perform AES shift rows operation for the whole AES block/state.

Definition at line 201 of file aes.c.

Referenced by cipherLookup().

00202 {
00203         byte temp;
00204 
00205         // Note: State is arranged column by column.
00206 
00207         // Cycle second row left one time.
00208         temp = state[ 1 + 0*4 ];
00209         state[ 1 + 0*4 ] = state[ 1 + 1*4 ];
00210         state[ 1 + 1*4 ] = state[ 1 + 2*4 ];
00211         state[ 1 + 2*4 ] = state[ 1 + 3*4 ];
00212         state[ 1 + 3*4 ] = temp;
00213 
00214         // Cycle third row left two times.
00215         temp = state[ 2 + 0*4 ];
00216         state[ 2 + 0*4 ] = state[ 2 + 2*4 ];
00217         state[ 2 + 2*4 ] = temp;
00218         temp = state[ 2 + 1*4 ];
00219         state[ 2 + 1*4 ] = state[ 2 + 3*4 ];
00220         state[ 2 + 3*4 ] = temp;
00221 
00222         // Cycle fourth row left three times, ie. right once.
00223         temp = state[ 3 + 3*4 ];
00224         state[ 3 + 3*4 ] = state[ 3 + 2*4 ];
00225         state[ 3 + 2*4 ] = state[ 3 + 1*4 ];
00226         state[ 3 + 1*4 ] = state[ 3 + 0*4 ];
00227         state[ 3 + 0*4 ] = temp;
00228 }

static void subBytes ( byte bytes,
byte  count 
) [static]

Substitute 'count' bytes in the 'bytes' buffer in SRAM using the S-Box.

Definition at line 186 of file aes.c.

References sBox.

Referenced by calcKeySchedule().

00187 {
00188         // Copy to temporary variables for optimization.
00189         byte * tempPtr = bytes;
00190         byte tempCount = count;
00191 
00192         do {
00193                 *tempPtr = sBox[ *tempPtr ]; // Substitute every byte in state.
00194                 ++tempPtr;
00195         } while( --tempCount );
00196 }


Variable Documentation

__no_init byte __eeprom keyScheduleInEEPROM[SCHEDULE_EXTRA]

Definition at line 58 of file aes.c.

Referenced by calcKeySchedule(), and cipherLookup().

byte keyScheduleInSRAM[SCHEDULE_SPLIT] [static]

Primary (SRAM) storage for key schedule.

Definition at line 62 of file aes.c.

Referenced by calcKeySchedule(), and cipherLookup().

const byte __flash sBox[256] [static]

S-Box lookup table.

Definition at line 65 of file aes.c.

Referenced by addConstantAndSubstitute(), addConstantFromEEPROMAndSubstitute(), and subBytes().

@DOC_TITLE@
Generated on Fri Aug 8 11:03:18 2008 for AVR411 Secure Rolling Code Algorithm (Transmitter) by doxygen 1.4.7