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