| 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 | addAndCopy (byte *buf1, byte *buf2, byte count) |
| static void | addConstantAndSubstitute (byte *bytes, const byte *constant, byte count) |
| static void | calcLastRoundKey (byte *scheduleBuffer) |
| void | cipher (byte *block, byte *scheduleBuffer, const byte *key) |
| static void | cycleLeft (byte *row) |
| void | invCipher (byte *block, byte *scheduleBuffer) |
| static void | invKeyExpansion (byte *scheduleBuffer, byte *roundConstant) |
| static void | invMixColumn (byte *column) |
| static void | invMixColumns (byte *state) |
| static void | invShiftRows (byte *state) |
| static void | invSubstituteAndAddConstant (byte *bytes, const byte *constant, byte count) |
| static void | keyExpansion (byte *scheduleBuffer, byte *roundConstant) |
| static void | mixColumn (byte *column) |
| static void | mixColumns (byte *state) |
| void | prepareInvCipher (byte *scheduleBuffer, const byte *key) |
| static void | shiftRows (byte *state) |
| static void | subBytes (byte *bytes, byte count) |
Variables | |
| const byte __flash | sBox [256] |
| const byte __flash | sBoxInv [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 invCipher(), invKeyExpansion(), invMixColumn(), keyExpansion(), and mixColumn().
XOR 'count' bytes from 'buf1' and 'buf2' buffers and copy result to both buffers.
Definition at line 467 of file aes.c.
Referenced by keyExpansion().
00468 { 00469 // Copy to temporary variables for optimization. 00470 byte * tempBuf1 = buf1; 00471 byte * tempBuf2 = buf2; 00472 byte tempCount = count; 00473 byte tempValue; 00474 00475 do { 00476 // Add in GF(2), ie. XOR. 00477 tempValue = *tempBuf1 ^ *tempBuf2; 00478 *tempBuf1++ = tempValue; 00479 *tempBuf2++ = tempValue; 00480 } while( --tempCount ); 00481 }
XOR 'count' bytes from 'constant' buffer into 'bytes' and substitute using S-Box.
Definition at line 508 of file aes.c.
References sBox.
Referenced by cipher().
00509 { 00510 // Copy to temporary variables for optimization. 00511 byte * tempDestination = bytes; 00512 const byte * tempSource = constant; 00513 byte tempCount = count; 00514 byte tempValue; 00515 00516 do { 00517 // Add in GF(2), ie. XOR. 00518 tempValue = *tempDestination ^ *tempSource++; 00519 *tempDestination++ = sBox[ tempValue ]; 00520 } while( --tempCount ); 00521 }
| static void calcLastRoundKey | ( | byte * | scheduleBuffer | ) | [static] |
Prepare last round key in schedule given the initial key in 'scheduleBuffer' and 'roundConstant'.
Definition at line 817 of file aes.c.
References keyExpansion(), ROUNDS, and SCHEDULE_BLOCK_REPETITIONS.
Referenced by prepareInvCipher().
00818 { 00819 byte roundConstant[ 4 ] = { 0x01, 0x00, 0x00, 0x00 }; 00820 00821 #if SCHEDULE_KEY_REPETITIONS > 1 00822 initialKeyExpansion( scheduleBuffer, roundConstant ); 00823 #endif 00824 00825 byte round; 00826 for( round = 1; round < ROUNDS+1; round += SCHEDULE_BLOCK_REPETITIONS ) { 00827 keyExpansion( scheduleBuffer, roundConstant ); 00828 } 00829 }
Here is the call graph for this function:

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:

| static void cycleLeft | ( | byte * | row | ) | [static] |
Cycle a 4-byte array left once.
Definition at line 134 of file aes.c.
Referenced by invKeyExpansion(), and keyExpansion().
00135 { 00136 // Cycle 4 bytes in an array left once. 00137 byte temp = row[0]; 00138 row[0] = row[1]; 00139 row[1] = row[2]; 00140 row[2] = row[3]; 00141 row[3] = temp; 00142 }
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:

Calculate previous round key from current round key in 'scheduleBuffer' and 'roundConstant'.
Definition at line 683 of file aes.c.
References addConstant(), BLOCK_SIZE, BPOLY, copyBytes(), cycleLeft(), KEY_SIZE, SCHEDULE_BUFFER_SIZE, and subBytes().
Referenced by invCipher().
00684 { 00685 byte tempWord[4]; 00686 00687 #if KEY_SIZE == 16 || KEY_SIZE == 32 00688 byte schedulePos = SCHEDULE_BUFFER_SIZE - 4; 00689 scheduleBuffer += SCHEDULE_BUFFER_SIZE - 4; 00690 00691 #if KEY_SIZE == 32 00692 do { 00693 // Add with previous word. 00694 addConstant( scheduleBuffer, scheduleBuffer - 4, 4 ); 00695 00696 // Move to previous word in schedule. 00697 scheduleBuffer -= 4; 00698 schedulePos -= 4; 00699 00700 } while( schedulePos > BLOCK_SIZE ); 00701 00702 // Prepare substitution of previous word. 00703 copyBytes( tempWord, scheduleBuffer - 4, 4 ); 00704 subBytes( tempWord, 4 ); 00705 00706 // Add substituted word to current word. 00707 addConstant( scheduleBuffer, tempWord, 4 ); 00708 00709 // Move to previous word in schedule. 00710 scheduleBuffer -= 4; 00711 schedulePos -= 4; 00712 #endif 00713 00714 do { 00715 // Add with previous word. 00716 addConstant( scheduleBuffer, scheduleBuffer - 4, 4 ); 00717 00718 // Move to previous word in schedule. 00719 scheduleBuffer -= 4; 00720 schedulePos -= 4; 00721 00722 } while( schedulePos > 0 ); 00723 00724 // Prepare round constant for transformation that follows. 00725 if( (roundConstant[0] ^ BPOLY) == 0 ) { 00726 roundConstant[0] = 0x80; 00727 } else { 00728 roundConstant[0] >>= 1; 00729 } 00730 00731 // Prepare transformation of previous word (which is now at end of buffer). 00732 copyBytes( tempWord, scheduleBuffer + SCHEDULE_BUFFER_SIZE - 4, 4 ); 00733 cycleLeft( tempWord ); 00734 subBytes( tempWord, 4 ); 00735 addConstant( tempWord, roundConstant, 4 ); 00736 00737 // Apply transformation result to current word. 00738 addConstant( scheduleBuffer, tempWord, 4 ); 00739 00740 #elif KEY_SIZE == 24 00741 // Move to end of first KEY_SIZE in schedule. 00742 byte schedulePos = (SCHEDULE_BUFFER_SIZE/2) - 4; 00743 scheduleBuffer += (SCHEDULE_BUFFER_SIZE/2) - 4; 00744 00745 do { 00746 // Get current word. 00747 // Add with previous word. 00748 // Store at position one KEY_SIZE backwards (wraps to end of buffer). 00749 addAndStore( scheduleBuffer, scheduleBuffer - 4, scheduleBuffer + KEY_SIZE, 4 ); 00750 00751 // Move to previous word in schedule. 00752 scheduleBuffer -= 4; 00753 schedulePos -= 4; 00754 00755 } while( schedulePos > 0 ); 00756 00757 // Prepare round constant for transformation that follows. 00758 if( (roundConstant[0] ^ BPOLY) == 0 ) { 00759 roundConstant[0] = 0x80; 00760 } else { 00761 roundConstant[0] >>= 1; 00762 } 00763 00764 // Prepare transformation of previous word (which is now at end of buffer). 00765 copyBytes( tempWord, scheduleBuffer + SCHEDULE_BUFFER_SIZE - 4, 4 ); 00766 cycleLeft( tempWord ); 00767 subBytes( tempWord, 4 ); 00768 addConstant( tempWord, roundConstant, 4 ); 00769 00770 // Add current word to transformation result. 00771 addConstant( tempWord, scheduleBuffer, 4 ); 00772 // Store at position one KEY_SIZE backwards (wraps to end of buffer). 00773 copyBytes( scheduleBuffer + KEY_SIZE, tempWord, 4 ); 00774 00775 // Move to last word in schedule. 00776 schedulePos = SCHEDULE_BUFFER_SIZE - 4; 00777 scheduleBuffer += SCHEDULE_BUFFER_SIZE - 4; 00778 00779 do { 00780 // Get current word. 00781 // Add with previous word. 00782 // Store at position one KEY_SIZE backwards. 00783 addAndStore( scheduleBuffer, scheduleBuffer - 4, scheduleBuffer - KEY_SIZE, 4 ); 00784 00785 // Move to previous word in schedule. 00786 scheduleBuffer -= 4; 00787 schedulePos -= 4; 00788 00789 } while( schedulePos > KEY_SIZE ); 00790 00791 // Prepare round constant for transformation that follows. 00792 if( (roundConstant[0] ^ BPOLY) == 0 ) { 00793 roundConstant[0] = 0x80; 00794 } else { 00795 roundConstant[0] >>= 1; 00796 } 00797 00798 // Prepare transformation of previous word. 00799 copyBytes( tempWord, scheduleBuffer - 4, 4 ); 00800 cycleLeft( tempWord ); 00801 subBytes( tempWord, 4 ); 00802 addConstant( tempWord, roundConstant, 4 ); 00803 00804 // Add current word to transformation result. 00805 addConstant( tempWord, scheduleBuffer, 4 ); 00806 // Store at position one KEY_SIZE backwards. 00807 copyBytes( scheduleBuffer - KEY_SIZE, tempWord, 4 ); 00808 00809 #else 00810 #error Unsupported key size. 00811 #endif 00812 }
Here is the call graph for this function:

| static void invMixColumn | ( | byte * | column | ) | [static] |
Perform an AES inverse column mix operation on the 4 bytes in 'column' buffer.
Definition at line 264 of file aes.c.
References BPOLY.
Referenced by invMixColumns().
00265 { 00266 byte result0, result1, result2, result3; 00267 byte column0, column1, column2, column3; 00268 byte xor; 00269 00270 // This generates more effective code, at least 00271 // with the IAR C compiler. 00272 column0 = column[0]; 00273 column1 = column[1]; 00274 column2 = column[2]; 00275 column3 = column[3]; 00276 00277 // Partial sums (modular addition using XOR). 00278 result0 = column1 ^ column2 ^ column3; 00279 result1 = column0 ^ column2 ^ column3; 00280 result2 = column0 ^ column1 ^ column3; 00281 result3 = column0 ^ column1 ^ column2; 00282 00283 // Multiply column bytes by 2 modulo BPOLY. 00284 // This operation is done the following way to ensure cycle count 00285 // independent from data contents. Take care when changing this code. 00286 xor = 0; 00287 if (column0 & 0x80) { 00288 xor = BPOLY; 00289 } 00290 column0 <<= 1; 00291 column0 ^= xor; 00292 00293 xor = 0; 00294 if (column1 & 0x80) { 00295 xor = BPOLY; 00296 } 00297 column1 <<= 1; 00298 column1 ^= xor; 00299 00300 xor = 0; 00301 if (column2 & 0x80) { 00302 xor = BPOLY; 00303 } 00304 column2 <<= 1; 00305 column2 ^= xor; 00306 00307 xor = 0; 00308 if (column3 & 0x80) { 00309 xor = BPOLY; 00310 } 00311 column3 <<= 1; 00312 column3 ^= xor; 00313 00314 // More partial sums. 00315 result0 ^= column0 ^ column1; 00316 result1 ^= column1 ^ column2; 00317 result2 ^= column2 ^ column3; 00318 result3 ^= column0 ^ column3; 00319 00320 // Multiply column bytes by 2 modulo BPOLY. 00321 // This operation is done the following way to ensure cycle count 00322 // independent from data contents. Take care when changing this code. 00323 xor = 0; 00324 if (column0 & 0x80) { 00325 xor = BPOLY; 00326 } 00327 column0 <<= 1; 00328 column0 ^= xor; 00329 00330 xor = 0; 00331 if (column1 & 0x80) { 00332 xor = BPOLY; 00333 } 00334 column1 <<= 1; 00335 column1 ^= xor; 00336 00337 xor = 0; 00338 if (column2 & 0x80) { 00339 xor = BPOLY; 00340 } 00341 column2 <<= 1; 00342 column2 ^= xor; 00343 00344 xor = 0; 00345 if (column3 & 0x80) { 00346 xor = BPOLY; 00347 } 00348 column3 <<= 1; 00349 column3 ^= xor; 00350 00351 // More partial sums. 00352 result0 ^= column0 ^ column2; 00353 result1 ^= column1 ^ column3; 00354 result2 ^= column0 ^ column2; 00355 result3 ^= column1 ^ column3; 00356 00357 // Multiply column bytes by 2 modulo BPOLY. 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 (column0 & 0x80) { 00362 xor = BPOLY; 00363 } 00364 column0 <<= 1; 00365 column0 ^= xor; 00366 00367 xor = 0; 00368 if (column1 & 0x80) { 00369 xor = BPOLY; 00370 } 00371 column1 <<= 1; 00372 column1 ^= xor; 00373 00374 xor = 0; 00375 if (column2 & 0x80) { 00376 xor = BPOLY; 00377 } 00378 column2 <<= 1; 00379 column2 ^= xor; 00380 00381 xor = 0; 00382 if (column3 & 0x80) { 00383 xor = BPOLY; 00384 } 00385 column3 <<= 1; 00386 column3 ^= xor; 00387 00388 // Final partial sum. 00389 column0 ^= column1 ^ column2 ^ column3; 00390 00391 // Final sums stored indto original column bytes. 00392 column[0] = result0 ^ column0; 00393 column[1] = result1 ^ column0; 00394 column[2] = result2 ^ column0; 00395 column[3] = result3 ^ column0; 00396 }
| static void invMixColumns | ( | byte * | state | ) | [static] |
Perform AES inverse column mixing for the whole AES block/state.
Definition at line 401 of file aes.c.
References invMixColumn().
Referenced by invCipher().
00402 { 00403 invMixColumn( state + 0*4 ); 00404 invMixColumn( state + 1*4 ); 00405 invMixColumn( state + 2*4 ); 00406 invMixColumn( state + 3*4 ); 00407 }
Here is the call graph for this function:

| static void invShiftRows | ( | byte * | state | ) | [static] |
Perform AES inverse shift rows operation for the whole AES block/state.
Definition at line 412 of file aes.c.
Referenced by invCipher().
00413 { 00414 byte temp; 00415 00416 // Note: State is arranged column by column. 00417 00418 // Cycle second row right one time. 00419 temp = state[ 1 + 3*4 ]; 00420 state[ 1 + 3*4 ] = state[ 1 + 2*4 ]; 00421 state[ 1 + 2*4 ] = state[ 1 + 1*4 ]; 00422 state[ 1 + 1*4 ] = state[ 1 + 0*4 ]; 00423 state[ 1 + 0*4 ] = temp; 00424 00425 // Cycle third row right two times. 00426 temp = state[ 2 + 0*4 ]; 00427 state[ 2 + 0*4 ] = state[ 2 + 2*4 ]; 00428 state[ 2 + 2*4 ] = temp; 00429 temp = state[ 2 + 1*4 ]; 00430 state[ 2 + 1*4 ] = state[ 2 + 3*4 ]; 00431 state[ 2 + 3*4 ] = temp; 00432 00433 // Cycle fourth row right three times, ie. left once. 00434 temp = state[ 3 + 0*4 ]; 00435 state[ 3 + 0*4 ] = state[ 3 + 1*4 ]; 00436 state[ 3 + 1*4 ] = state[ 3 + 2*4 ]; 00437 state[ 3 + 2*4 ] = state[ 3 + 3*4 ]; 00438 state[ 3 + 3*4 ] = temp; 00439 }
| static void invSubstituteAndAddConstant | ( | byte * | bytes, | |
| const byte * | constant, | |||
| byte | count | |||
| ) | [static] |
Substitute 'count' bytes from 'bytes' using inverse S-Box, XOR with 'constant' and store in 'bytes'.
Definition at line 526 of file aes.c.
References sBoxInv.
Referenced by invCipher().
00527 { 00528 // Copy to temporary variables for optimization. 00529 byte * tempDestination = bytes; 00530 const byte * tempSource = constant; 00531 byte tempCount = count; 00532 byte tempValue; 00533 00534 do { 00535 // Add in GF(2), ie. XOR. 00536 tempValue = *tempDestination; 00537 *tempDestination++ = sBoxInv[ tempValue ] ^ *tempSource++; 00538 } while( --tempCount ); 00539 }
Calculates next round key from current round key in 'scheduleBuffer' and 'roundConstant'.
Definition at line 544 of file aes.c.
References addAndCopy(), addConstant(), BLOCK_SIZE, BPOLY, copyBytes(), cycleLeft(), KEY_SIZE, SCHEDULE_BUFFER_SIZE, and subBytes().
Referenced by calcLastRoundKey(), and cipher().
00545 { 00546 byte tempWord[4]; 00547 byte schedulePos = 0; 00548 00549 // Get last word from previous schedule buffer. 00550 copyBytes( tempWord, scheduleBuffer + SCHEDULE_BUFFER_SIZE - 4, 4 ); 00551 00552 // Transform it, since we are at a KEY_SIZE boundary in the schedule. 00553 cycleLeft( tempWord ); 00554 subBytes( tempWord, 4 ); 00555 addConstant( tempWord, roundConstant, 4 ); 00556 00557 // Update round constant. 00558 if( roundConstant[0] & 0x80 ) { 00559 roundConstant[0] <<= 1; 00560 roundConstant[0] ^= BPOLY; 00561 } else { 00562 roundConstant[0] <<= 1; 00563 } 00564 00565 #if KEY_SIZE == 16 || KEY_SIZE == 32 00566 00567 #if KEY_SIZE == 32 00568 do { 00569 // Add value from one KEY_SIZE backwards, ie. in last schedule buffer. 00570 // Store in buffer, replacing old value, which was one KEY_SIZE backwards. 00571 addAndCopy( tempWord, scheduleBuffer, 4 ); 00572 00573 // Move to next word in schedule buffer. 00574 scheduleBuffer += 4; 00575 schedulePos += 4; 00576 00577 } while( schedulePos < BLOCK_SIZE ); 00578 00579 // Substitute previous word when at BLOCK_SIZE boundary with 256 bit keys. 00580 subBytes( tempWord, 4 ); 00581 #endif 00582 00583 do { 00584 // Add value from one KEY_SIZE backwards, ie. in last schedule buffer. 00585 // Store in buffer, replacing old value, which was one KEY_SIZE backwards. 00586 addAndCopy( tempWord, scheduleBuffer, 4 ); 00587 00588 // Move to next word in schedule buffer. 00589 scheduleBuffer += 4; 00590 schedulePos += 4; 00591 00592 } while( schedulePos < SCHEDULE_BUFFER_SIZE ); 00593 00594 #elif KEY_SIZE == 24 00595 do { 00596 // Add value from one KEY_SIZE backwards (wraps to end of buffer). 00597 // Store in buffer, replacing old value. 00598 addConstantAndCopy( tempWord, scheduleBuffer + KEY_SIZE, scheduleBuffer, 4 ); 00599 00600 // Move to next word in schedule buffer. 00601 scheduleBuffer += 4; 00602 schedulePos += 4; 00603 00604 } while( schedulePos < KEY_SIZE ); 00605 00606 // Transform previous word, since we are at a KEY_SIZE boundary in the schedule. 00607 cycleLeft( tempWord ); 00608 subBytes( tempWord, 4 ); 00609 addConstant( tempWord, roundConstant, 4 ); 00610 00611 // Update round constant. 00612 if( roundConstant[0] & 0x80 ) { 00613 roundConstant[0] <<= 1; 00614 roundConstant[0] ^= BPOLY; 00615 } else { 00616 roundConstant[0] <<= 1; 00617 } 00618 00619 do { 00620 // Add value from one KEY_SIZE backwards. 00621 // Store in buffer, replacing old value. 00622 addConstantAndCopy( tempWord, scheduleBuffer - KEY_SIZE, scheduleBuffer, 4 ); 00623 00624 // Move to next word in schedule buffer. 00625 scheduleBuffer += 4; 00626 schedulePos += 4; 00627 00628 } while( schedulePos < SCHEDULE_BUFFER_SIZE ); 00629 00630 #else 00631 #error Unsupported key size. 00632 #endif 00633 }
Here is the call graph for this function:

| static void mixColumn | ( | byte * | column | ) | [static] |
Perform an AES column mix operation on the 4 bytes in 'column' buffer.
Definition at line 147 of file aes.c.
References BPOLY.
Referenced by mixColumns().
00148 { 00149 byte result0, result1, result2, result3; 00150 byte column0, column1, column2, column3; 00151 00152 // This generates more effective code, at least 00153 // with the IAR C compiler. 00154 column0 = column[0]; 00155 column1 = column[1]; 00156 column2 = column[2]; 00157 column3 = column[3]; 00158 00159 // Partial sums (modular addition using XOR). 00160 result0 = column1 ^ column2 ^ column3; 00161 result1 = column0 ^ column2 ^ column3; 00162 result2 = column0 ^ column1 ^ column3; 00163 result3 = column0 ^ column1 ^ column2; 00164 00165 // Multiply column bytes by 2 modulo BPOLY. 00166 // This operation is done the following way to ensure cycle count 00167 // independent from data contents. Take care when changing this code. 00168 xor = 0; 00169 if (column0 & 0x80) { 00170 xor = BPOLY; 00171 } 00172 column0 <<= 1; 00173 column0 ^= xor; 00174 00175 xor = 0; 00176 if (column1 & 0x80) { 00177 xor = BPOLY; 00178 } 00179 column1 <<= 1; 00180 column1 ^= xor; 00181 00182 xor = 0; 00183 if (column2 & 0x80) { 00184 xor = BPOLY; 00185 } 00186 column2 <<= 1; 00187 column2 ^= xor; 00188 00189 xor = 0; 00190 if (column3 & 0x80) { 00191 xor = BPOLY; 00192 } 00193 column3 <<= 1; 00194 column3 ^= xor; 00195 00196 // Final sums stored into original column bytes. 00197 column[0] = result0 ^ column0 ^ column1; 00198 column[1] = result1 ^ column1 ^ column2; 00199 column[2] = result2 ^ column2 ^ column3; 00200 column[3] = result3 ^ column0 ^ column3; 00201 }
| static void mixColumns | ( | byte * | state | ) | [static] |
Perform AES column mixing for the whole AES block/state.
Definition at line 206 of file aes.c.
References mixColumn().
Referenced by cipher().
00207 { 00208 mixColumn( state + 0*4 ); 00209 mixColumn( state + 1*4 ); 00210 mixColumn( state + 2*4 ); 00211 mixColumn( state + 3*4 ); 00212 }
Here is the call graph for this function:

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:

| static void shiftRows | ( | byte * | state | ) | [static] |
Perform AES shift-rows operation for the whole AES block/state.
Definition at line 232 of file aes.c.
Referenced by cipher().
00233 { 00234 byte temp; 00235 00236 // Note: State is arranged column by column. 00237 00238 // Cycle second row left one time. 00239 temp = state[ 1 + 0*4 ]; 00240 state[ 1 + 0*4 ] = state[ 1 + 1*4 ]; 00241 state[ 1 + 1*4 ] = state[ 1 + 2*4 ]; 00242 state[ 1 + 2*4 ] = state[ 1 + 3*4 ]; 00243 state[ 1 + 3*4 ] = temp; 00244 00245 // Cycle third row left two times. 00246 temp = state[ 2 + 0*4 ]; 00247 state[ 2 + 0*4 ] = state[ 2 + 2*4 ]; 00248 state[ 2 + 2*4 ] = temp; 00249 temp = state[ 2 + 1*4 ]; 00250 state[ 2 + 1*4 ] = state[ 2 + 3*4 ]; 00251 state[ 2 + 3*4 ] = temp; 00252 00253 // Cycle fourth row left three times, ie. right once. 00254 temp = state[ 3 + 3*4 ]; 00255 state[ 3 + 3*4 ] = state[ 3 + 2*4 ]; 00256 state[ 3 + 2*4 ] = state[ 3 + 1*4 ]; 00257 state[ 3 + 1*4 ] = state[ 3 + 0*4 ]; 00258 state[ 3 + 0*4 ] = temp; 00259 }
Substitute 'count' bytes in the 'bytes' buffer in SRAM using the S-Box.
Definition at line 217 of file aes.c.
References sBox.
Referenced by invKeyExpansion(), and keyExpansion().
00218 { 00219 // Copy to temporary variables for optimization. 00220 byte * tempPtr = bytes; 00221 byte tempCount = count; 00222 00223 do { 00224 *tempPtr = sBox[ *tempPtr ]; // Substitute every byte in state. 00225 ++tempPtr; 00226 } while( --tempCount ); 00227 }
S-Box lookup table.
Definition at line 60 of file aes.c.
Referenced by addConstantAndSubstitute(), and subBytes().
Inverse S-Box lookup table.
Definition at line 96 of file aes.c.
Referenced by invSubstituteAndAddConstant().
Generated on Fri Aug 8 11:03:51 2008 for AVR411 Secure Rolling Code Algorithm (Receiver) by 1.4.7
|