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