| Remote Access Control | |||||
This file contains the function implementation for the AES algorithm. Refer to the aes.h file for more details.
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 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().
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 }
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 }
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 }
| __no_init byte __eeprom keyScheduleInEEPROM[SCHEDULE_EXTRA] |
byte keyScheduleInSRAM[SCHEDULE_SPLIT] [static] |
Primary (SRAM) storage for key schedule.
Definition at line 62 of file aes.c.
Referenced by calcKeySchedule(), and cipherLookup().
S-Box lookup table.
Definition at line 65 of file aes.c.
Referenced by addConstantAndSubstitute(), addConstantFromEEPROMAndSubstitute(), and subBytes().
Generated on Fri Aug 8 11:03:18 2008 for AVR411 Secure Rolling Code Algorithm (Transmitter) by 1.4.7
|