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