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