Wiselib
|
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