Wiselib
wiselib.testing/algorithms/crypto/eschenauer_gligor/aes.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  ** This file is part of the generic algorithm library Wiselib.           **
00003  ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project.      **
00004  **                                                                       **
00005  ** The Wiselib is free software: you can redistribute it and/or modify   **
00006  ** it under the terms of the GNU Lesser General Public License as        **
00007  ** published by the Free Software Foundation, either version 3 of the    **
00008  ** License, or (at your option) any later version.                       **
00009  **                                                                       **
00010  ** The Wiselib is distributed in the hope that it will be useful,        **
00011  ** but WITHOUT ANY WARRANTY; without even the implied warranty of        **
00012  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
00013  ** GNU Lesser General Public License for more details.                   **
00014  **                                                                       **
00015  ** You should have received a copy of the GNU Lesser General Public      **
00016  ** License along with the Wiselib.                                       **
00017  ** If not, see <http://www.gnu.org/licenses/>.                           **
00018  **                                                                       **
00019  ** Improved by: Christoph Knecht, University of Bern 2010                **
00020  ***************************************************************************/
00021 #ifndef __ALGORITHMS_CRYPTO_AES_H__
00022 #define __ALGORITHMS_CRYPTO_AES_H__
00023 
00024 #include <string.h>
00025 
00026 // xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}
00027 #define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))
00028 
00029 // The number of columns comprising a state in AES. This is a constant in AES. Value=4
00030 #define Nb 4
00031 
00032 namespace wiselib
00033 {
00034 template<typename OsModel_P>
00035 class AES
00036    {
00037    public:
00038       typedef OsModel_P OsModel;
00039 
00042       AES();
00043       ~AES();
00045 
00048       void enable( void );
00049       void disable( void );
00051 
00053       void encrypt( uint8_t*, uint8_t* );
00054       void decrypt( uint8_t*, uint8_t* );
00055 
00056       //initialize keys
00057       void key_setup( uint8_t*, uint16_t );
00058 
00059    private:
00060 
00061     // The number of rounds in AES Cipher.The actual value is received in the program.
00062     int8_t Nr;
00063 
00064     // The number of 32 bit words in the key.The actual value is received in the program.
00065     int8_t Nk;
00066 
00067     // state - the array that holds the intermediate results during encryption.
00068     uint8_t state[4][4];
00069 
00070     // The array that stores the round keys.
00071     uint8_t RoundKey[240];
00072 
00073     // The round constant word array, Rcon[i], contains the values given by
00074     // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(28)
00075     // Note that i starts at 1, not 0).
00076     uint8_t getRconValue(int16_t num)
00077     {
00078     uint8_t Rcon[255] ={
00079             0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
00080             0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
00081             0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
00082             0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
00083             0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
00084             0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
00085             0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
00086             0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
00087             0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
00088             0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
00089             0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
00090             0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
00091             0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
00092             0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
00093             0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
00094             0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb };
00095     return Rcon[num];
00096     }
00097 
00098     //SBox
00099     uint8_t getSBoxValue(int16_t num)
00100     {
00101             uint8_t sbox[256] =   {
00102             //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
00103             0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
00104             0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
00105             0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
00106             0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
00107             0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
00108             0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
00109             0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
00110             0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
00111             0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
00112             0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
00113             0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
00114             0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
00115             0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
00116             0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
00117             0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
00118             0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
00119             return sbox[num];
00120     }
00121 
00122     //inverse Sbox
00123     uint8_t getSBoxInvert(int16_t num)
00124     {
00125     uint8_t rsbox[256] =
00126     { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
00127     , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
00128     , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
00129     , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
00130     , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
00131     , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
00132     , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
00133     , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
00134     , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
00135     , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
00136     , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
00137     , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
00138     , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
00139     , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
00140     , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
00141     , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
00142 
00143     return rsbox[num];
00144     }
00145 
00146     // Multiplty is a macro used to multiply numbers in the field GF(2^8)
00147          uint8_t xtimes(uint8_t a , uint8_t b)
00148          {
00149                  uint8_t result = 0;
00150 
00151                         int8_t count = 8;
00152                         while (count--)
00153                                 {
00154                                 if (b&1)
00155                                         result ^= a;
00156                                 if (a&128)
00157                                         {
00158                                         a <<= 1;
00159                                         a ^= (0x11B&255);
00160                                         }
00161                                 else
00162                                         a <<= 1;
00163                                 b >>= 1;
00164                                 }
00165                         return result;
00166          }
00167 
00168     // This function produces Nb(Nr+1) round keys. The round keys are used in each round to encrypt the states.
00169     void KeyExpansion(uint8_t * Key)
00170     {
00171             int8_t i,j;
00172             uint8_t temp[4],k;
00173 
00174             // The first round key is the key itself.
00175             for(i=0;i<Nk;i++)
00176             {
00177                     RoundKey[i*4]=Key[i*4];
00178                     RoundKey[i*4+1]=Key[i*4+1];
00179                     RoundKey[i*4+2]=Key[i*4+2];
00180                     RoundKey[i*4+3]=Key[i*4+3];
00181             }
00182 
00183             // All other round keys are found from the previous round keys.
00184             while (i < (Nb * (Nr+1)))
00185             {
00186                                             for(j=0;j<4;j++)
00187                                             {
00188                                                     temp[j]=RoundKey[(i-1) * 4 + j];
00189                                             }
00190                                             if (i % Nk == 0)
00191                                             {
00192                                                     // This function rotates the 4 bytes in a word to the left once.
00193                                                     // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]
00194 
00195                                                     // Function RotWord()
00196                                                     {
00197                                                             k = temp[0];
00198                                                             temp[0] = temp[1];
00199                                                             temp[1] = temp[2];
00200                                                             temp[2] = temp[3];
00201                                                             temp[3] = k;
00202                                                     }
00203 
00204                                                     // SubWord() is a function that takes a four-byte input word and
00205                                                     // applies the S-box to each of the four bytes to produce an output word.
00206 
00207                                                     // Function Subword()
00208                                                     {
00209                                                             temp[0]=getSBoxValue(temp[0]);
00210                                                             temp[1]=getSBoxValue(temp[1]);
00211                                                             temp[2]=getSBoxValue(temp[2]);
00212                                                             temp[3]=getSBoxValue(temp[3]);
00213                                                     }
00214 
00215                                                     temp[0] =  temp[0] ^ getRconValue(i/Nk);
00216                                             }
00217                                             else if (Nk > 6 && i % Nk == 4)
00218                                             {
00219                                                     // Function Subword()
00220                                                     {
00221                                                             temp[0]=getSBoxValue(temp[0]);
00222                                                             temp[1]=getSBoxValue(temp[1]);
00223                                                             temp[2]=getSBoxValue(temp[2]);
00224                                                             temp[3]=getSBoxValue(temp[3]);
00225                                                     }
00226                                             }
00227                                             RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];
00228                                             RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];
00229                                             RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];
00230                                             RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];
00231                                             i++;
00232             }
00233     }
00234 
00235     // This function adds the round key to state.
00236     // The round key is added to the state by an XOR function.
00237     void AddRoundKey(int8_t round)
00238     {
00239             int8_t i,j;
00240             for(i=0;i<4;i++)
00241             {
00242                     for(j=0;j<4;j++)
00243                     {
00244                             state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
00245                     }
00246             }
00247     }
00248 
00249     // The SubBytes Function Substitutes the values in the
00250     // state matrix with values in an S-box.
00251     void SubBytes()
00252     {
00253             int8_t i,j;
00254             for(i=0;i<4;i++)
00255             {
00256                     for(j=0;j<4;j++)
00257                     {
00258                             state[i][j] = getSBoxValue(state[i][j]);
00259 
00260                     }
00261             }
00262     }
00263 
00264     // The InvSubBytes Function Substitutes the values in the
00265     // state matrix with values in an inverted S-box.
00266     void InvSubBytes()
00267     {
00268             int8_t i,j;
00269             for(i=0;i<4;i++)
00270             {
00271                     for(j=0;j<4;j++)
00272                     {
00273                             state[i][j] = getSBoxInvert(state[i][j]);
00274 
00275                     }
00276             }
00277     }
00278 
00279     // The ShiftRows() function shifts the rows in the state to the left.
00280     // Each row is shifted with different offset.
00281     // Offset = Row number. So the first row is not shifted.
00282     void ShiftRows()
00283     {
00284             uint8_t temp;
00285 
00286             // Rotate first row 1 columns to left
00287             temp=state[1][0];
00288             state[1][0]=state[1][1];
00289             state[1][1]=state[1][2];
00290             state[1][2]=state[1][3];
00291             state[1][3]=temp;
00292 
00293             // Rotate second row 2 columns to left
00294             temp=state[2][0];
00295             state[2][0]=state[2][2];
00296             state[2][2]=temp;
00297 
00298             temp=state[2][1];
00299             state[2][1]=state[2][3];
00300             state[2][3]=temp;
00301 
00302             // Rotate third row 3 columns to left
00303             temp=state[3][0];
00304             state[3][0]=state[3][3];
00305             state[3][3]=state[3][2];
00306             state[3][2]=state[3][1];
00307             state[3][1]=temp;
00308     }
00309 
00310     // The InvShiftRows() function shifts the rows in the state to the right.
00311     // Each row is shifted with different offset.
00312     // Offset = Row number. So the first row is not shifted.
00313     void InvShiftRows()
00314     {
00315             uint8_t temp;
00316 
00317             // Rotate first row 1 columns to right
00318             temp=state[1][3];
00319             state[1][3]=state[1][2];
00320             state[1][2]=state[1][1];
00321             state[1][1]=state[1][0];
00322             state[1][0]=temp;
00323 
00324             // Rotate second row 2 columns to right
00325             temp=state[2][0];
00326             state[2][0]=state[2][2];
00327             state[2][2]=temp;
00328 
00329             temp=state[2][1];
00330             state[2][1]=state[2][3];
00331             state[2][3]=temp;
00332 
00333             // Rotate third row 3 columns to right
00334             temp=state[3][0];
00335             state[3][0]=state[3][1];
00336             state[3][1]=state[3][2];
00337             state[3][2]=state[3][3];
00338             state[3][3]=temp;
00339     }
00340 
00341     // MixColumns function mixes the columns of the state matrix
00342     void MixColumns()
00343     {
00344             int8_t i;
00345             uint8_t Tmp,Tm,t;
00346             for(i=0;i<4;i++)
00347             {
00348                     t=state[0][i];
00349                     Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;
00350                     Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp ;
00351                     Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp ;
00352                     Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp ;
00353                     Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp ;
00354             }
00355     }
00356 
00357     // InvMixColumns function mixes the columns of the state matrix.
00358     // The method used to multiply may be difficult to understand for the inexperienced.
00359     // Please use the references to gain more information.
00360     void InvMixColumns()
00361     {
00362             int8_t i;
00363             uint8_t a,b,c,d;
00364             uint8_t x1=0x0e;
00365             uint8_t x2=0x09;
00366             uint8_t x3=0x0d;
00367             uint8_t x4=0x0b;
00368 
00369             for(i=0;i<4;i++)
00370             {
00371 
00372                     a = state[0][i];
00373                     b = state[1][i];
00374                     c = state[2][i];
00375                     d = state[3][i];
00376 
00377 
00378                     state[0][i] = xtimes(a, x1) ^ xtimes(b, x4) ^ xtimes(c, x3) ^ xtimes(d, x2);
00379                     state[1][i] = xtimes(a, x2) ^ xtimes(b, x1) ^ xtimes(c, x4) ^ xtimes(d, x3);
00380                     state[2][i] = xtimes(a, x3) ^ xtimes(b, x2) ^ xtimes(c, x1) ^ xtimes(d, x4);
00381                     state[3][i] = xtimes(a, x4) ^ xtimes(b, x3) ^ xtimes(c, x2) ^ xtimes(d, x1);
00382             }
00383     }
00384 };
00385 
00386 // -----------------------------------------------------------------------
00387 template<typename OsModel_P>
00388 AES<OsModel_P>::
00389 AES()
00390 {
00391 }
00392 
00393 // -----------------------------------------------------------------------
00394 template<typename OsModel_P>
00395 AES<OsModel_P>::
00396 ~AES()
00397 {
00398 }
00399 
00400 // -----------------------------------------------------------------------
00401 template<typename OsModel_P>
00402 void
00403 AES<OsModel_P>::
00404 enable( void )
00405 {
00406 }
00407 
00408 // -----------------------------------------------------------------------
00409 template<typename OsModel_P>
00410 void
00411 AES<OsModel_P>::
00412 disable( void )
00413 {
00414 }
00415 
00416 //-------------------------------------------------------------------
00417 template<typename OsModel_P>
00418 void
00419 AES<OsModel_P>::
00420 encrypt( uint8_t * in, uint8_t * out )
00421 {
00422         int8_t i,j,round=0;
00423 
00424         //Copy the input PlainText to state array.
00425         for(i=0;i<4;i++)
00426         {
00427                 for(j=0;j<4;j++)
00428                 {
00429                         state[j][i] = in[i*4 + j];
00430                 }
00431         }
00432 
00433         // Add the First round key to the state before starting the rounds.
00434         AddRoundKey(0);
00435 
00436         // There will be Nr rounds.
00437         // The first Nr-1 rounds are identical.
00438         // These Nr-1 rounds are executed in the loop below.
00439         for(round=1;round<Nr;round++)
00440         {
00441                 SubBytes();
00442                 ShiftRows();
00443                 MixColumns();
00444                 AddRoundKey(round);
00445         }
00446 
00447         // The last round is given below.
00448         // The MixColumns function is not here in the last round.
00449         SubBytes();
00450         ShiftRows();
00451         AddRoundKey(Nr);
00452 
00453         // The encryption process is over.
00454         // Copy the state array to output array.
00455         for(i=0;i<4;i++)
00456         {
00457                 for(j=0;j<4;j++)
00458                 {
00459                         out[i*4+j]=state[j][i];
00460                 }
00461         }
00462 }
00463 
00464 //--------------------------------------------------------------
00465 template<typename OsModel_P>
00466 void
00467 AES<OsModel_P>::
00468 decrypt( uint8_t * in, uint8_t * out )
00469 {
00470         int8_t i,j,round=0;
00471 
00472         //Copy the input CipherText to state array.
00473         for(i=0;i<4;i++)
00474         {
00475                 for(j=0;j<4;j++)
00476                 {
00477                         state[j][i] = in[i*4 + j];
00478                 }
00479         }
00480 
00481         // Add the First round key to the state before starting the rounds.
00482         AddRoundKey(Nr);
00483 
00484         // There will be Nr rounds.
00485         // The first Nr-1 rounds are identical.
00486         // These Nr-1 rounds are executed in the loop below.
00487         for(round=Nr-1;round>0;round--)
00488         {
00489                 InvShiftRows();
00490                 InvSubBytes();
00491                 AddRoundKey(round);
00492                 InvMixColumns();
00493         }
00494 
00495         // The last round is given below.
00496         // The MixColumns function is not here in the last round.
00497         InvShiftRows();
00498         InvSubBytes();
00499         AddRoundKey(0);
00500 
00501         // The decryption process is over.
00502         // Copy the state array to output array.
00503         for(i=0;i<4;i++)
00504         {
00505                 for(j=0;j<4;j++)
00506                 {
00507                         out[i*4+j]=state[j][i];
00508                 }
00509         }
00510 }
00511 //--------------------------------------------------------------------
00512 template<typename OsModel_P>
00513 void
00514 AES<OsModel_P>::
00515 key_setup( uint8_t *key, uint16_t  key_size )
00516 {
00517         if( key_size == 128 )
00518         {
00519                 Nk=4;
00520                 Nr=10;
00521                 KeyExpansion( key );
00522         }
00523         else if( key_size == 192 )
00524         {
00525                 Nk=6;
00526                 Nr=12;
00527                 KeyExpansion( key );
00528         }
00529         else if( key_size == 256 )
00530         {
00531                 Nk=8;
00532                 Nr=14;
00533                 KeyExpansion( key );
00534         }
00535         else
00536         {
00537                 //os().debug("Key Length not supported");
00538         }
00539 }
00540 
00541 }
00542 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines